k次取反后最大化的数组和
这里的局部最优思想就是让绝对值最大的数变成正数
若将负数都转变味正数了,k依然大于0,涉及到第二个贪心,则只将最小的数反转
细节:
1. 先排序, 把负数放在前面
2. 遍历, 如果k>0, 同时数字为负数时, 就反转
3. 再排序一次, 如果还有k,就把前面小的反转
4. 最后遍历所有的加起来
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
Arrays.sort(nums);
int sum = 0;
for(int i = 0; i < nums.length; i++){
if(k > 0 && nums[i] < 0){
nums[i] = -nums[i];
k--;
}
}
//然后再排序一遍, 把小的放在前面
//把k用完, 由于排序, 直接换第一个就行了
Arrays.sort(nums);
if(k % 2 == 1){
nums[0] = -nums[0];
}
//最后把数字加起来
for(int n : nums){
sum += n;
}
return sum;
}
}
加油站
由于时间关系, 放到周末再进行处理
分发糖果
思想就是既要考虑比右边大, 也要考虑比左边大, 而必须要确定一边之后, 再确定另一边:
- 一次是从左到右遍历,只比较右边孩子评分比左边大的情况。
- 一次是从右到左遍历,只比较左边孩子评分比右边大的情况。
- 第二次遍历有两种情况, 要么是之前的, 要么是在右边基础上加一, 判断max
class Solution {
public int candy(int[] ratings) {
int len = ratings.length;
int[] candyNum = new int[len];
//需要初始化变成1, 不然的话下面遍历时就会出错
Arrays.fill(candyNum, 1);
//开始从左往右遍历, 判断右边比左边大
for(int i = 1; i < len; i++){
if(ratings[i] > ratings[i - 1]){
candyNum[i] = candyNum[i - 1] + 1;
}
}
//第二个遍历, 从右到左遍历, 判断左边比右边大
//注意这里的边界
for(int i = len - 2; i >= 0; i--){
if(ratings[i] > ratings[i + 1]){
//有两种情况
candyNum[i] = Math.max(candyNum[i], candyNum[i + 1] + 1);
}
}
//把candyNum加起来
int res = 0;
for(int candy : candyNum){
res += candy;
}
return res;
}
}