算法练习day29

63 阅读2分钟

一、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)
};