一、K次取反后最大化的数组和
局部最优,将绝对值大的负数变为正数,如果k大于0,将数值最小的正整数反转
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var largestSumAfterKNegations = function(nums, k) {
nums.sort((x, y) => Math.abs(y) - Math.abs(x))
for(let i = 0; i < nums.length;i++) {
if(nums[i] < 0 && k > 0) {
nums[i] = -nums[i]
k--
}
}
while(k > 0) {
nums[nums.length - 1] = -nums[nums.length - 1]
k--
}
return nums.reduce((sum, cur) => sum + cur)
};
二、加油站
暴力解法
/**
* @param {number[]} gas
* @param {number[]} cost
* @return {number}
*/
var canCompleteCircuit = function(gas, cost) {
for(let i = 0; i < cost.length;i++) {
let res = gas[i] - cost[i]
let index = (i + 1) % cost.length
// 模拟以i为起点行驶一圈(如果有rest==0,那么答案就不唯一了)
while(res > 0 && index !== i) {
res += gas[index] - cost[index]
index = (index + 1) % cost.length
}
if(res >= 0 && index === i) {
return i
}
}
return -1
};
如果剩余油量总和小于0,则不可能跑完一圈
如果剩余最小油量大于0,则返回0
否则从后往前,把这个最小剩余油量填满的时候,说明该位置可以跑完一圈
var canCompleteCircuit = function(gas, cost) {
let sum = 0
let min = Infinity
for(let i = 0; i < gas.length;i++) {
sum += gas[i] - cost[i]
min = Math.min(min, sum)
}
if(min >= 0) {
return 0
}
if(sum < 0) {
return -1
}
sum = 0
for(let i = gas.length - 1; i>=0;i--) {
sum += gas[i] - cost[i]
if(sum + min >= 0) {
return i
}
}
return -1
};
贪心思路
var canCompleteCircuit = function(gas, cost) {
let start = 0
let curSum = 0
let totalSum = 0
for(let i = 0; i < gas.length; i++) {
curSum += gas[i] - cost[i]
totalSum += gas[i] - cost[i]
if(curSum < 0) {
start = i + 1
curSum = 0
}
}
if(totalSum < 0) {
return -1
}
return start
};
三、分发糖果
先从左往右遍历,比较 左值和右值,确定右值的结果 从右往左遍历,比较 右值和左值,确定左值的结果
/**
* @param {number[]} ratings
* @return {number}
*/
var candy = function(ratings) {
let res = new Array(ratings.length).fill(1)
for(let i = 1; i < ratings.length;i++) {
if(ratings[i] > ratings[i-1]) {
res[i] = res[i-1] + 1
}
}
for(let i = ratings.length - 2; i >= 0;i--) {
if(ratings[i] > ratings[i+1]) {
res[i] = Math.max(res[i], res[i+1] + 1)
}
}
return res.reduce((sum, cur) => sum + cur)
};