攻克代码随想录 | 1005. K 次取反后最大化的数组和 | 134. 加油站 | 135. 分发糖果

1005. K 次取反后最大化的数组和

1005. K次取反后最大化的数组和
首先,我们应当将数组从小到大排序,然后开始新的判定:若第一个数为负数,则取反并继续迭代,直至数组出现正数或0/全部迭代完成/k降至0. 出现0的时候就可以直接开始累加了,因为0无论取反多少次都是0,出现正数则考虑k的模,并对此时最小的正整数进行来回取反。
当然,在这题我们还忽略了一种情形:全是负数且迭代完k仍大于0.此时,我们应当重新排序,并且对最小的正数进行来回取反处理。

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var largestSumAfterKNegations = function(nums, k) {
    nums.sort((a, b) => a - b);
    // console.log(nums);
    for(let i = 0;i < nums.length;i++){
        if(nums[i] < 0){
            nums[i] = -nums[i];
            console.log(nums[i]);
            k--;
        }
        else if(nums[i] > 0){
            nums.sort((a, b) => a - b);
            if(k % 2 === 1){
                nums[0] = -nums[0];
            }
            break;
        }
        if(nums[i] === 0 || k === 0) break;
    }
    nums.sort((a, b) => a - b);
    while(nums[0] > 0 && k > 0){
        if(k % 2 === 1){
            nums[0] = -nums[0];
        }
        break;
    }
    let sum = 0;
    for(const num of nums){
        sum += num;
    }
    return sum;
    
};

134. 加油站

134. 加油站
①先两个数组循环一遍,若gas的累计总和小于cost,则直接返回-1.
②计算minusGasCost = gas[i] - cost [i],声明lowest = 0,将每次的min(minusGasCost,lowest)赋值给lowest。若lowest遍历完等于0,则返回第一个索引。
③若lowest小于0,则从尾到头开始遍历,开始不断补齐最小值,当出现大于等于0时,则该值为起始索引。

/**
 * @param {number[]} gas
 * @param {number[]} cost
 * @return {number}
 */
var canCompleteCircuit = function(gas, cost) {
    let sumGas = 0, sumCost = 0;
    for(let i = 0; i < gas.length;i++){
        sumGas += gas[i];
    }
    for(let j = 0; j < gas.length;j++){
        sumCost += cost[j];
    }
    if(sumGas < sumCost) return -1;
    let lowest = 0, minusGasCost = 0;
    for(let i = 0; i < gas.length;i++){
        minusGasCost += gas[i] - cost[i];
        lowest = minusGasCost < lowest ? minusGasCost : lowest;
    }
    if(lowest === 0) return 0;
    for(let j = gas.length - 1;j >= 0;j--){
        lowest += gas[j] - cost[j];
        if(lowest >= 0) return j;
    }
};

135. 分发糖果

135. 分发糖果
先创造一个全为1的数组。
从左往右遍历,若右大于左,则右等于左+1.
从右往左遍历,若左大于右,则左等于max(右+1,左)。

/**
 * @param {number[]} ratings
 * @return {number}
 */
var candy = function(ratings) {
    let count = 0;
    let nums = new Array(ratings.length).fill(1);
    for(let i = 1;i < ratings.length;i++){
        if(ratings[i] > ratings[i - 1]) nums[i] = nums[i - 1] + 1;
    }
    for(let j = ratings.length - 2; j >= 0;j--){
        if(ratings[j] > ratings[j + 1]) nums[j] = nums[j] > nums[j + 1] + 1 ? nums[j] : nums[j + 1] + 1;
    }
    for(const num of nums){
        count += num;
        console.log(num);
    }
    return count;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值