bash
第八章 贪心算法 part03
● 1005.K次取反后最大化的数组和
● 134. 加油站
● 135. 分发糖果
详细布置
1005.K次取反后最大化的数组和
本题简单一些,估计大家不用想着贪心 ,用自己直觉也会有思路。
https://programmercarl.com/1005.K%E6%AC%A1%E5%8F%96%E5%8F%8D%E5%90%8E%E6%9C%80%E5%A4%A7%E5%8C%96%E7%9A%84%E6%95%B0%E7%BB%84%E5%92%8C.html
134. 加油站
本题有点难度,不太好想,推荐大家熟悉一下方法二
https://programmercarl.com/0134.%E5%8A%A0%E6%B2%B9%E7%AB%99.html
135. 分发糖果
本题涉及到一个思想,就是想处理好一边再处理另一边,不要两边想着一起兼顾,后面还会有题目用到这个思路
https://programmercarl.com/0135.%E5%88%86%E5%8F%91%E7%B3%96%E6%9E%9C.html
往日任务
● day 1 任务以及具体安排:https://docs.qq.com/doc/DUG9UR2ZUc3BjRUdY
● day 2 任务以及具体安排:https://docs.qq.com/doc/DUGRwWXNOVEpyaVpG
● day 3 任务以及具体安排:https://docs.qq.com/doc/DUGdqYWNYeGhlaVR6
● day 4 任务以及具体安排:https://docs.qq.com/doc/DUFNjYUxYRHRVWklp
● day 5 周日休息
● day 6 任务以及具体安排:https://docs.qq.com/doc/DUEtFSGdreWRuR2p4
● day 7 任务以及具体安排:https://docs.qq.com/doc/DUElCb1NyTVpXa0Jj
● day 8 任务以及具体安排:https://docs.qq.com/doc/DUGdsY2JFaFhDRVZH
● day 9 任务以及具体安排:https://docs.qq.com/doc/DUHVXSnZNaXpVUHN4
● day 10 任务以及具体安排:https://docs.qq.com/doc/DUElqeHh3cndDbW1Q
●day 11 任务以及具体安排:https://docs.qq.com/doc/DUHh6UE5hUUZOZUd0
●day 12 周日休息
●day 13 任务以及具体安排:https://docs.qq.com/doc/DUHNpa3F4b2dMUWJ3
●day 14 任务以及具体安排:https://docs.qq.com/doc/DUHRtdXZZSWFkeGdE
●day 15 任务以及具体安排:https://docs.qq.com/doc/DUHN0ZVJuRmVYeWNv
●day 16 任务以及具体安排:https://docs.qq.com/doc/DUHBQRm1aSWR4T2NK
●day 17 任务以及具体安排:https://docs.qq.com/doc/DUFpXY3hBZkpabWFY
●day 18 任务以及具体安排:https://docs.qq.com/doc/DUFFiVHl3YVlReVlr
●day 19 周日休息
●day 20 任务以及具体安排:https://docs.qq.com/doc/DUGFRU2V6Z1F4alBH
●day 21 任务以及具体安排:https://docs.qq.com/doc/DUHl2SGNvZmxqZm1X
●day 22 任务以及具体安排:https://docs.qq.com/doc/DUHplVUp5YnN1bnBL
●day 23 任务以及具体安排:https://docs.qq.com/doc/DUFBUQmxpQU1pa29C
●day 24 任务以及具体安排:https://docs.qq.com/doc/DUEhsb0pUUm1WT2NP
●day 25 任务以及具体安排:https://docs.qq.com/doc/DUExTYXVzU1BiU2Zl
●day 26 休息
●day 27 任务以及具体安排:https://docs.qq.com/doc/DUElpbnNUR3hIbXlY
●day 28 任务以及具体安排:https://docs.qq.com/doc/DUG1yVHdlWEdNYlhZ
●day 29 任务以及具体安排:https://docs.qq.com/doc/DUHZYbWhwSHRCRmp3
●day 30 任务以及具体安排:https://docs.qq.com/doc/DUEdTVVhxbnJiY3BR
●day 31 任务以及具体安排:https://docs.qq.com/doc/DUG1PQ1ZZY2xXY1ly
●day 32 任务以及具体安排:https://docs.qq.com/doc/DUGFEdGFWeVhleFF1
●day 33 周日休息
目录
1005_K次取反后最大化的数组和
Java中使用Streams对数组进行求和的代码。
Arrays.stream(nums)
将整型数组nums
转换为一个流,然后通过调用.sum()
方法对流中的所有元素进行求和。Arrays.stream(nums).sum();
java
package com.question.solve.leetcode.programmerCarl2._09_greedyAlgorithms;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;
public class _1005_K次取反后最大化的数组和 {
}
class Solution1005 {
public int largestSumAfterKNegations(int[] nums, int K) {
//将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
nums = IntStream.of(nums)
.boxed()
.sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
.mapToInt(Integer::intValue).toArray();
int len = nums.length;
for (int i = 0; i < len; i++) {
//从前向后遍历,遇到负数将其变为正数,同时K--
if (nums[i] < 0 && K > 0) {
nums[i] = -nums[i];
K--;
}
}
//如果K还大于0,那么反复转变数值最小的元素,将K用完
if (K % 2 == 1)
nums[len - 1] = -nums[len - 1];
return Arrays.stream(nums).sum();
}
}
class Solution1005_2 {
public int largestSumAfterKNegations(int[] nums, int k) {
Map<Integer, Integer> freq = new HashMap<Integer, Integer>();
for (int num : nums) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
int ans = Arrays.stream(nums).sum();
for (int i = -100; i < 0; ++i) {
if (freq.containsKey(i)) {
int ops = Math.min(k, freq.get(i));
ans += (-i) * ops * 2;
freq.put(i, freq.get(i) - ops);
freq.put(-i, freq.getOrDefault(-i, 0) + ops);
k -= ops;
if (k == 0) {
break;
}
}
}
if (k > 0 && k % 2 == 1 && !freq.containsKey(0)) {
for (int i = 1; i <= 100; ++i) {
if (freq.containsKey(i)) {
ans -= i * 2;
break;
}
}
}
return ans;
}
}
class Solution1005_3 {
public int largestSumAfterKNegations(int[] nums, int k) {
//排序,把可能有的负数排到前面
Arrays.sort(nums);
int sum = 0;
for (int i = 0; i < nums.length; i++) {
//贪心:如果是负数,而k还有盈余,就把负数反过来
if (nums[i] < 0 && k > 0) {
nums[i] = -1 * nums[i];
k--;
}
sum += nums[i];
}
Arrays.sort(nums);
//如果k没剩,那说明能转的负数都转正了,已经是最大和了,返回sum
//如果k有剩,说明负数已经全部转正,所以如果k还剩偶数个就自己抵消掉,不用删减,如果k还剩奇数个就减掉2倍最小正数。
return sum - (k % 2 == 0 ? 0 : 2 * nums[0]);
}
}
0134_加油站
java
package com.question.solve.leetcode.programmerCarl2._09_greedyAlgorithms;
public class _0134_加油站 {
}
class Solution0134 {//解法1
public int canCompleteCircuit(int[] gas, int[] cost) {
int sum = 0;
int min = 0;
for (int i = 0; i < gas.length; i++) {
sum += (gas[i] - cost[i]);
min = Math.min(sum, min);
}
if (sum < 0) return -1;
if (min >= 0) return 0;
for (int i = gas.length - 1; i > 0; i--) {
min += (gas[i] - cost[i]);
if (min >= 0) return i;
}
return -1;
}
}
class Solution0134_2 {//解法2
public int canCompleteCircuit(int[] gas, int[] cost) {
int curSum = 0;
int totalSum = 0;
int index = 0;
for (int i = 0; i < gas.length; i++) {
curSum += gas[i] - cost[i];
totalSum += gas[i] - cost[i];
if (curSum < 0) {
index = (i + 1) % gas.length;
curSum = 0;
}
}
if (totalSum < 0) return -1;
return index;
}
}
0135_分发糖果
java
package com.question.solve.leetcode.programmerCarl2._09_greedyAlgorithms;
public class _0135_分发糖果 {
}
class Solution0135 {
/**
* 分两个阶段
* 1、起点下标1 从左往右,只要 右边 比 左边 大,右边的糖果=左边 + 1
* 2、起点下标 ratings.length - 2 从右往左, 只要左边 比 右边 大,
* 此时 左边的糖果应该 取本身的糖果数(符合比它左边大) 和 右边糖果数 + 1 二者的最大值,
* 这样才符合 它比它左边的大,也比它右边大
*/
public int candy(int[] ratings) {
int len = ratings.length;
int[] candyVec = new int[len];
candyVec[0] = 1;
for (int i = 1; i < len; i++) {
candyVec[i] = (ratings[i] > ratings[i - 1]) ? candyVec[i - 1] + 1 : 1;
}
for (int i = len - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1]) {
candyVec[i] = Math.max(candyVec[i], candyVec[i + 1] + 1);
}
}
int ans = 0;
for (int num : candyVec) {
ans += num;
}
return ans;
}
}