517. 超级洗衣机
2021.9.29 每日一题
题目描述
假设有 n 台超级洗衣机放在同一排上。开始的时候,每台洗衣机内可能有一定量的衣服,也可能是空的。
在每一步操作中,你可以选择任意 m (1 <= m <= n) 台洗衣机,与此同时将每台洗衣机的一件衣服送到相邻的一台洗衣机。
给定一个整数数组 machines 代表从左至右每台洗衣机中的衣物数量,请给出能让所有洗衣机中剩下的衣物的数量相等的 最少的操作步数 。如果不能使每台洗衣机中衣物的数量相等,则返回 -1 。
示例 1:
输入:machines = [1,0,5]
输出:3
解释:
第一步: 1 0 <-- 5 => 1 1 4
第二步: 1 <-- 1 <-- 4 => 2 1 3
第三步: 2 1 <-- 3 => 2 2 2
示例 2:
输入:machines = [0,3,0]
输出:2
解释:
第一步: 0 <-- 3 0 => 1 2 0
第二步: 1 2 --> 0 => 1 1 1
示例 3:
输入:machines = [0,2,0]
输出:-1
解释:
不可能让所有三个洗衣机同时剩下相同数量的衣物。
提示:
n == machines.length
1 <= n <= 10^4
0 <= machines[i] <= 10^5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/super-washing-machines
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
近期第一个不会做的每日一题
这个题确实不知道怎么想
class Solution {
public int findMinMoves(int[] machines) {
//我想的很直观的思路,多退少补
//不够,就从多的地方补足;多了,就分给别的地方
//从左到右补足,肯定是最少的操作
//是贪心的思路,但是写了一下代码,太复杂
//还是想想怎么简单点写
//突然发现,因为多余的地方肯定要把多余的衣服送到别的地方,所以需要送m[i] - avg次
//而补足也是同理,要补足,需要avg - m[i]次
//而在它移动的时候,其他相邻的也在移动,所以肯定能这些次数内送完
//但是在补足的时候,可能出现连续的0,就需要有多次的移动
int l = machines.length;
int sum = 0;
for(int m : machines){
sum += m;
}
if(sum % l != 0)
return -1;
int avg = sum / l;
int left = 0;
int right = sum;
int res = 0;
for(int i = 0; i < l; i++){
right -= machines[i]; //右边部分的值
//左边填平需要的衣服数目
int a = Math.max(0, i * avg - left);
int b = Math.max(0, (l - i - 1) * avg - right);
res = Math.max(res, a + b);
left += machines[i];
}
return res;
}
}
//思考一下官解的思路
//首先,也是根据每个位置是要移出还是补齐来看的
//但是这里用了一个将洗衣机分成两组的操作,
//将衣服分成两组,然后多的往少的运,因为题目要求每次只能移动一个衣服,所以是合理的
//但是可能有一种情况,就是某一个位置衣服很多,然后这个位置需要往两边运输,
//第二个情况,就是我之前写的这种,将最多的洗衣机里的衣服移出去
//然后三叶姐的思路呢,就是按一个位置,将衣服分成左右两堆,然后判断左右各需要多少个衣服才能填平
//因为左右和中间是分开的,所以就不需要分类讨论了
//所以这个题的关键点,还是要想到,如果A部分比B部分多,那么衣服移动的次数就是A-B
官解这种思路,题目要求的是最小值,但是这里为什么要取最大值呢
其实这里最大值和题目要求的最小值没有关系,这里取最大值是贪心取得的每个机器最小运输数量的最大值,而贪心取的是每个机器的最下运输数量,
是要保证在max移动次数下,肯定能保持平衡,而其他位置求得的值,内部还需要另外去平衡,所以不能算做答案
而这个max其实就是贪心取得的运输次数的最小值
class Solution {
public int findMinMoves(int[] machines) {
//官解思路
int l = machines.length;
int sum = 0;
for(int m : machines){
sum += m;
}
if(sum % l != 0)
return -1;
int avg = sum / l;
int res = 0;
int pre = 0; //记录左边衣服情况
for(int i = 0; i < l; i++){
//这个需要num个才能变成avg
int num = machines[i] - avg;
pre += num;
//然后两种情况求最大
int temp = Math.max(num, Math.abs(pre));
res = Math.max(res, temp);
}
return res;
}
}
要从每个机器的最小运输次数这个角度出发,计算衣服经过每个机器的次数;而所有机器中的最大值,就是衣服移动的最小次数
明确这个点以后,再明确两个部分移动次数,就是取差值;但是有可能一个位置衣服过多,需要内部平衡,所以另外考虑这种情况
难
223. 矩形面积
2021.9.30 每日一题,9月打卡完毕了
题目描述
给你 二维 平面上两个 由直线构成的 矩形,请你计算并返回两个矩形覆盖的总面积。
每个矩形由其 左下 顶点和 右上 顶点坐标表示:
第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。
第二个矩形由其左下顶点 (bx1, by1) 和右上顶点 (bx2, by2) 定义。
示例 1:
输入:ax1 = -3, ay1 = 0, ax2 = 3, ay2 = 4, bx1 = 0, by1 = -1, bx2 = 9, by2 = 2
输出:45
示例 2:
输入:ax1 = -2, ay1 = -2, ax2 = 2, ay2 = 2, bx1 = -2, by1 = -2, bx2 = 2, by2 = 2
输出:16
提示:
-10^4 <= ax1, ay1, ax2, ay2, bx1, by1, bx2, by2 <= 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rectangle-area
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
说真的,没有想到怎么计算重叠部分的面积
看了官解,才明悟
自己写的详细了点,加强理解记忆
class Solution {
public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
//这题怎么做...,代码写起来感觉有点困难啊......
//大的减小的吗,还是计算重合部分的面积...
//首先计算两个矩形的面积,因为是左下和右上,所以直接算就行了
int area1 = (ax2 - ax1) * (ay2 - ay1);
int area2 = (bx2 - bx1) * (by2 - by1);
//然后投影到x轴上的四个点
int left = Math.max(ax1, bx1);
int right = Math.min(ax2, bx2);
//投影到y轴上的四个点
int up = Math.min(ay2, by2);
int down = Math.max(ay1, by1);
int x = right - left;
int y = up - down;
//如果小于0说明不相交
if(x <= 0 || y <= 0)
return area1 + area2;
else
return area1 + area2 - x * y;
}
}
1436. 旅行终点站
2021.10.1 每日一题
题目描述
给你一份旅游线路图,该线路图中的旅行线路用数组 paths 表示,其中 paths[i] = [cityAi, cityBi] 表示该线路将会从 cityAi 直接前往 cityBi 。请你找出这次旅行的终点站,即没有任何可以通往其他城市的线路的城市。
题目数据保证线路图会形成一条不存在循环的线路,因此恰有一个旅行终点站。
示例 1:
输入:paths = [[“London”,“New York”],[“New York”,“Lima”],[“Lima”,“Sao Paulo”]]
输出:“Sao Paulo”
解释:从 “London” 出发,最后抵达终点站 “Sao Paulo” 。本次旅行的路线是 “London” -> “New York” -> “Lima” -> “Sao Paulo” 。
示例 2:
输入:paths = [[“B”,“C”],[“D”,“B”],[“C”,“A”]]
输出:“A”
解释:所有可能的线路是:
“D” -> “B” -> “C” -> “A”.
“B” -> “C” -> “A”.
“C” -> “A”.
“A”.
显然,旅行终点站是 “A” 。
示例 3:
输入:paths = [[“A”,“Z”]]
输出:“Z”
提示:
1 <= paths.length <= 100
paths[i].length == 2
1 <= cityAi.length, cityBi.length <= 10
cityAi != cityBi
所有字符串均由大小写英文字母和空格字符组成。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/destination-city
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
其实力扣每次假期选的题都是有节日气氛的
class Solution {
public String destCity(List<List<String>> paths) {
Map<String, String> roads = new HashMap<>();
for(List<String> list : paths){
String a = list.get(0);
String b = list.get(1);
roads.put(a, b);
}
String start = paths.get(0).get(0);
while(roads.containsKey(start)){
start = roads.get(start);
}
return start;
}
}