学习目标:
60天训练营打卡计划!
学习内容:
1005.K次取反后最大化的数组和
- 本题的策略可分为两次贪心:
① 第一次贪心是将所有的负数都变为正数
② 第二次贪心是选择牺牲一个最小的数,使其取反直至满足题目的要求取反次数。 - java中没有使用树数值绝对值对数组排序的api,所以要回忆排序算法
- 八嘎,我忘记了。。。
- 插入排序温习
引用自hello算法:https://www.hello-algo.com/chapter_sorting/insertion_sort/
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
// 使用自定义的Comparator对绝对值进行排序
// 要学会呀。。。
// Arrays.sort(nums, new Comparator<Integer>(){
// @Override
// public int compare(Integer a, Integer b){
// return Math.abs(a) - Math.abs(b);
// }
// });
// 使用插入排序按绝对值大小对数组进行排序
for (int i = 1; i < nums.length; i++) {
int key = nums[i];
int j = i - 1;
while (j >= 0 && Math.abs(nums[j]) < Math.abs(key)) {
nums[j + 1] = nums[j];
j--;
}
nums[j + 1] = key;
}
for(int i = 0; i < nums.length; i++){
if(nums[i] < 0 && k > 0){
nums[i] *= -1;
k--;
}
}
if(k % 2 == 1) nums[nums.length - 1] *= -1;
return Arrays.stream(nums).sum();
}
}
134.加油站
- 不理解这个为什么是贪心算法,确实很难想。
- 操作非常的巧妙:通过使用for循环从头开始计数可以避免对数组进行环的操作
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int start = 0;
int curGas = 0;
int totalGas = 0;
// 使用for循环从头开始计数可以避免对数组进行环的操作
for(int i = 0; i < gas.length; i++){
curGas += gas[i] - cost[i];
totalGas += gas[i] - cost[i];
// 局部贪心就是这一段的净油量大于0
if(curGas < 0){
start = i + 1;
curGas = 0;
}
}
if(totalGas < 0) return -1;
return start;
}
}
135.分发糖果
- 这个题目的精髓在于分别处理比左边大和比右边大,从两次的结果中取出最大的结果。
- 不懂为什么是贪心算法,迷茫。。。
class Solution {
public int candy(int[] ratings) {
int size = ratings.length;
int[] res = new int[size];
res[0] = 1;
for(int i = 1; i < size; i++){
res[i] = 1;
// 从左向右比,大于左边则加1.
if(ratings[i] > ratings[i-1]){
res[i] = res[i-1] + 1;
}
}
for(int i = size - 2; i >= 0; i--){
// 从右向左比,大于右则加1.
if(ratings[i] > ratings[i+1]){
res[i] = Math.max(res[i], res[i+1] + 1);
}
}
return Arrays.stream(res).sum();
}
}
学习时间:
- 上午两个小时,整理文档半小时。