diff --git a/problems/0134.加油站.md b/problems/0134.加油站.md index c88b43b1..1329bd9a 100644 --- a/problems/0134.加油站.md +++ b/problems/0134.加油站.md @@ -249,6 +249,29 @@ class Solution { } } ``` +``` +// 解法3 +class Solution { + public int canCompleteCircuit(int[] gas, int[] cost) { + int tank = 0; // 当前油量 + int totalGas = 0; // 总加油量 + int totalCost = 0; // 总油耗 + int start = 0; // 起点 + for (int i = 0; i < gas.length; i++) { + totalGas += gas[i]; + totalCost += cost[i]; + + tank += gas[i] - cost[i]; + if (tank < 0) { // tank 变为负数 意味着 从0到i之间出发都不能顺利环路一周,因为在此i点必会没油 + tank = 0; // reset tank,类似于题目53.最大子树和reset sum + start = i + 1; // 起点变为i点往后一位 + } + } + if (totalCost > totalGas) return -1; + return start; + } +} +``` ### Python 暴力法 diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index fa27d3b7..4e049600 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -128,6 +128,36 @@ class Solution { } } + +// 版本二:排序数组并贪心地尽可能将负数翻转为正数,再根据剩余的k值调整最小元素的符号,从而最大化数组的总和。 +class Solution { + public int largestSumAfterKNegations(int[] nums, int k) { + if (nums.length == 1) return nums[0]; + + // 排序:先把负数处理了 + Arrays.sort(nums); + + for (int i = 0; i < nums.length && k > 0; i++) { // 贪心点, 通过负转正, 消耗尽可能多的k + if (nums[i] < 0) { + nums[i] = -nums[i]; + k--; + } + } + + // 退出循环, k > 0 || k < 0 (k消耗完了不用讨论) + if (k % 2 == 1) { // k > 0 && k is odd:对于负数:负-正-负-正 + Arrays.sort(nums); // 再次排序得到剩余的负数,或者最小的正数 + nums[0] = -nums[0]; + } + // k > 0 && k is even,flip数字不会产生影响: 对于负数: 负-正-负;对于正数:正-负-正 + + int sum = 0; + for (int num : nums) { // 计算最大和 + sum += num; + } + return sum; + } +} ``` ### Python