一、1005.K次取反后最大化的数组和
- 按绝对值从大到小排序,然后贪心:先变绝对值大的且为负数的
- 这里学习一下:Lambda表达式中,是对于Integer类型的数组排序的。
int[] nums = new int[]{1,2,3};
Integer[] arr = new Integer[nums.length];
for (int i = 0; i < nums.length; i++) {
arr[i] = nums[i];
}
Arrays.sort(arr, (a, b) -> (b - a));//从大到小排序
Arrays.sort(arr, (a,b) -> (Math.abs(b)-Math.abs(a));//按绝对值从大到小排序
public int largestSumAfterKNegations(int[] nums, int k) {
Integer[] arr= new Integer[nums.length];
for (int i = 0; i < nums.length; i++) {
arr[i] = nums[i];
}
Arrays.sort(arr,(a,b)->(Math.abs(b)-Math.abs(a)));//按绝对值从大到小排序,然后先变绝对值大的
for(int i=0;i<arr.length;i++){
if(k>0&&arr[i]<0){
k--;
arr[i]=arr[i]*-1;
}
}
if(k>0&&k%2==1){
arr[arr.length-1]*=-1;
}
int sum=0;
for(int i=0;i<arr.length;i++){
sum += arr[i];
}
return sum;
}
11分钟
二、134. 加油站
- 先加油,再消耗。
- 一旦curSum小于零,说明[0, i]区间都不能作为起始位置,那么起始位置从i+1算起,再从0计算curSum。
public int canCompleteCircuit(int[] gas, int[] cost) {
int curSum = 0;
int totalSum = 0;
int start = 0;
for (int i = 0; i < gas.length; i++) {
curSum += gas[i]-cost[i];
totalSum += gas[i]-cost[i];
if (curSum<0) {
start = i+1;
curSum=0;
}
}
if (totalSum<0) return -1;
else return start;
}
39分钟
三、135. 分发糖果
- 需要考虑两边的情况。先确定一边,再确定另一边。
- 分两个阶段
1、起点下标1 从左往右,只要 右边 比 左边 大,右边的糖果=左边 + 1
2、起点下标 ratings.length - 2 从右往左, 只要左边 比 右边 大,此时 左边的糖果应该 取本身的糖果数(符合比它左边大) 和 右边糖果数 + 1 二者的最大值,这样才符合 它比它左边的大,也比它右边大 - 易错点:
candy[i]=candy[i-1]+1;
而不是candy[i]+=1;
是比左边大1。
public int candy(int[] ratings) {
int[] candy = new int[ratings.length];
Arrays.fill(candy,1);
for(int i=1;i<candy.length;i++){
if(ratings[i]>ratings[i-1]){
// candy[i]+=1;
candy[i]=Math.max(candy[i-1]+1;//注意这里
}
}
for(int i=candy.length-2;i>=0;i--){//注意是从后面开始遍历
if(ratings[i]>ratings[i+1]){
candy[i]=Math.max(candy[i], candy[i+1]+1);
}
}
int num=0;
for(int i=0;i<candy.length;i++){
num+=candy[i];
}
return num;
}
20分钟