134.加油站
如下图所示:
当索引一道2的时候,剩余油量的总量=1+3-6 < 0,这个时候说明以索引0为起点不合适,将起点更新为索引3.
两点证明:
1.如果我们从蓝色段中间选一个点开始,是不是最后sumGas就不小于0?
不会,我们可以看如下图,如果蓝色sumGas<0,sumGas1>0==>可以推出sumGas2<0,这样就不符合我们在蓝色段结束才sumGas<0的条件。
2.最终所有的剩余油量相加大于等于0就一定可以跑完一圈吗?
一定会,可以这样想:
这个图画成一个环形图,前进方向为顺时针。假设totalsum=0,那么走一圈油量和消耗抵消下来就为0(先不管油够不够走到每一站),假设从起点到第i点油量不够消耗,那么从i点继续走回起点油量就肯定大于消耗,因为总油量和消耗相等。那么答案很明显了,我既然从起点顺时针走到i点又不够,那我从i点顺时针走回起点油就够了。
406.根据身高重建队列
这道题目分为两步:
1.将数组中的元素按照身高降序排列,如果身高相同,按照前面的人数升序排列
2.将每一个元素按照前面的人数插入对应的位置
第一步满足了所有元素使降序排列,当元素往前面插入的时候不会影响其他元素满足前面的人数的条件。
class Solution {
public int[][] reconstructQueue(int[][] people) {
// 身高从大到小排(身高相同k小的站前面)
Arrays.sort(people, (a, b) -> {
if (a[0] == b[0]) return a[1] - b[1]; // a - b 是升序排列,故在a[0] == b[0]的狀況下,會根據k值升序排列
return b[0] - a[0]; //b - a 是降序排列,在a[0] != b[0],的狀況會根據h值降序排列
});
LinkedList<int[]> que = new LinkedList<>();
for (int[] p : people) {
que.add(p[1],p); //Linkedlist.add(index, value),會將value插入到指定index裡。
}
return que.toArray(new int[people.length][]);
}
}
135. 分发糖果
思路:数组从左向右遍历一遍,如果右大于左,置为加一
再从右向左遍历一遍,如果左大于右,置为加一
class Solution {
public int candy(int[] ratings) {
//思路:数组从左向右遍历一遍,如果右大于左,置为加一
//再从右向左遍历一遍,如果左大于右,置为加一
int len = ratings.length;
int[] candyArr = new int[len];
candyArr[0] = 1;
//从左向右
for(int i = 1;i < len;i++){
if(ratings[i-1] < ratings[i]){
candyArr[i] = candyArr[i-1] + 1;
}else{
candyArr[i] = 1;
}
}
//从右向左
for(int i = len-2;i >= 0;i--){
if(ratings[i] > ratings[i+1]){
candyArr[i] = Math.max(candyArr[i],candyArr[i+1]+1); //必须保证既比右边大又比左边大
}
}
int totalNum = 0;
for(int n:candyArr){
totalNum += n;
}
return totalNum;
}
}