-
1005. K次取反后最大化的数组和
【思路】要最后数组的和最大,那么就要取反后的数值最大,那么就要判断负数和正数,正负数越小的取反,就可以按照绝对值的大小排列然后负数的取反,遇到有 0 的就都取0,当把所有的负数都变为正数之后,若 k 还有值,就取反最小的正数,若剩余的 k 值是偶数的时候,双数次取反还是正数,直接返回结果,若剩余 k 的值为奇数时,减去两倍的最小的值(因为 for 循环里计算和加了一次,最后取反为负数了又要减去一次,所以总共要减去两次)。var largestSumAfterKNegations = function(nums, k) { let sortNums = nums.sort((a, b) => Math.abs(b) - Math.abs(a)), sum = 0; for (let i = 0; i < sortNums.length; i++) { if (k > 0 && sortNums[i] <= 0) { sortNums[i] = -sortNums[i]; k--; } sum += sortNums[i]; } if (k % 2 > 0) sum -= 2 * sortNums[sortNums.length - 1]; return sum; };
-
134. 加油站
【思路】 如果总油量减去总耗油量小于 0,那么说明跑不完一圈(即各个加油站储油量减去对应的耗油量之和小于 0),就返回 -1。如果加油站储油量减去耗油量小于 0,那么说明不是七点位置,起点位置往后移一位。var canCompleteCircuit = function(gas, cost) { let sum = 0, start = 0, rest = 0; for (let i = 0; i < gas.length; i ++) { rest += gas[i] - cost[i]; sum += gas[i] - cost[i]; if (rest < 0) { // 如果为负数,证明油不够去下一个站点了,不可以从当前位置循环,开始下标应该变为下一个 start = i + 1; rest = 0; } } if (sum < 0) return -1; // 如果 sum 为负数,就证明走完一圈所消耗的油量大于所有加油站里储存的油量 return start; };
-
135. 分发糖果
【思路】要比较相邻两遍的评分,同时比较左右两边有点困难,可以两次 for 循环,分别和左右两边进行比较,注意加糖果时是在什么基础上加。var candy = function(ratings) { let sum = 0, candyArr = new Array(ratings.length).fill(1); // 假设每个人刚开始都有一个糖果 // 从左向右遍历:查找右边比左边大的评分,多发一个糖果 for (let i = 0; i < ratings.length; i++) { if (ratings[i + 1] > ratings[i]) candyArr[i + 1] = candyArr[i] + 1; // 参考 [1,2,87,87,87,2,1] 时,评分连续递增时,要在上一个评分的基础上加一个糖果 } // 从右向左遍历:查找左边比右边大的评分,多发一个糖果 for (let i = ratings.length - 1; i >= 0; i--) { if (ratings[i - 1] > ratings[i]) { if (candyArr[i - 1] <= candyArr[i]) candyArr[i - 1] = candyArr[i] + 1; // 参考 [1,3,2,2,1]、[1,3,4,5,2],要根据当前遍历的数值与前一个下标的数值的大小判断是否加一个糖果 } sum += candyArr[i] } return sum; };
参考代码随想录:https://www.programmercarl.com/