day 34 K次取反后的最大数值||加油站||分发糖果

// /**
//  * @param {number[]} nums
//  * @param {number} k
//  * @return {number}
//  */
// var largestSumAfterKNegations = function(nums, k) {
// // 1 将数组按照绝对值大小从大到小排序 
// // 2 从前向后遍历 遇到负数将其变为正数 同时k--
// // 3 如果K还大于0 那么反复转变数值最小的元素 将k用完
// // 4 求和

// // 按照绝对值 从大到小如何排序
// // nums.sort((a,b)=>Math.abs(b)-Math.abs(a))

// // 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--;
// // }
// // // reduce() 方法接收一个函数作为累加器 数组中每个值开始缩减(从左到右) 最终计算为一个值
// // return nums.reduce((a,b)=>{
// //     a+b;
// // })
// nums.sort((a,b) => Math.abs(b) - Math.abs(a))
    
//     for(let i = 0 ;i < nums.length; i++){
//         if(nums[i] < 0 && k > 0){
//             nums[i] = - nums[i];
//             k--;
//         }
//     }

//     // 若k还大于0,则寻找最小的数进行不断取反
//     while( k > 0 ){
//         nums[nums.length-1] = - nums[nums.length-1]
//         k--;
//     }
//     return nums.reduce((a, b) => {
//          a + b
//     })
// };

var largestSumAfterKNegations = function(nums, k) {

    nums.sort((a,b) => Math.abs(b) - Math.abs(a))
    
    for(let i = 0 ;i < nums.length; i++){
        if(nums[i] < 0 && k > 0){
            nums[i] = - nums[i];
            k--;
        }
    }

    // 若k还大于0,则寻找最小的数进行不断取反
    while( k > 0 ){
        nums[nums.length-1] = - nums[nums.length-1]
        k--;
    }
    let sum=0
    for(let i=0;i<nums.length;i++){
        sum+=nums[i]
    }
    return sum
};

答案上的reduce不行!!

思路

如何让数组和最大呢?

贪心:局部最优 :让绝对值大的负数变正数,当前数值最大,

整体最优

如果负数都转变为正了,k依然大于0,此时的问题是一个有序正数序列,如何转变k次正负,让数组和达到最大。

又是一个贪心:只找数值最小的正整数进行反转。

思路

贪心:如果总油量减去总消耗大于等于0 一定可以跑完一圈,

说明各个站点的加油量 剩油量rest[i]相加一定>=0

从0开始累加rest[i] 和记为curSum 一但curSum<0 0-i 区间不能作为起始位置

因为这个区间选择任何一个位置作为起点,到这里都会断油 

那么起始位置从i+1 算起 再从0计算curSum

那么局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。全局最优:找到可以跑一圈的起始位置

分发糖果

那么本题我采用了两次贪心的策略:

  • 一次是从左到右遍历,只比较右边孩子评分比左边大的情况。
  • 一次是从右到左遍历,只比较左边孩子评分比右边大的情况。

这样从局部最优推出了全局最优,即:相邻的孩子中,评分高的孩子获得更多的糖果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值