LeetCode 1005. K 次取反后最大化的数组和 java题解

https://leetcode.cn/problems/maximize-sum-of-array-after-k-negations/description/

看着简单但是写si人的一题。

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        Arrays.sort(nums);//排序
        int last_negative=-1,first_positive=-1;//最后一个负数位置,第一个正数位置
        //计数
        int count_zero=0;
        int count_negative=0;
        int count_positive=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]<0){//负数
                last_negative=i;
                count_negative++;
            }
            else if(nums[i]>0){//正数
                if(count_positive==0){//前面,没有出现过正数
                    first_positive=i;
                }
                count_positive++;
            }
            else{//0
                count_zero++;
            }
        }

//开始变化
        if(count_negative>=k){//1.有足够的负数。负数变正数。
            for(int i=0;i<k;i++){//修改k次
                nums[i]=-nums[i];
            }
        }
        else if(0<count_negative&&count_negative<k){//2.有负数,但不够。
            //先修改已有的负数
            for(int i=0;i<count_negative;i++){//从前到后,修改所有负数。剩下的交给0
                nums[i]=-nums[i];
            }      
            int left=k-count_negative;//还需要修改的次数
            if(left%2==0){// 2.1 还剩下偶数次
                //不用改了
            }
            
            //2.2 有零。修改0
            else if(count_zero>0){
                //也可以说不用改了
            }
            else{//2.3 有负数,但不够,还剩奇数次,还没有0
                int a=Integer.MAX_VALUE;
                int b=Integer.MAX_VALUE;
                if(count_positive>0){//有正数
                    a=nums[first_positive];
                }
                if(count_negative>0){
                    b=nums[last_negative];
                }
                //取绝对值小的数
                if(Math.abs(a)<Math.abs(b)){
                    nums[first_positive]=-nums[first_positive];
                }
                else{
                    nums[last_negative]=-nums[last_negative];
                }
            }
        }
        else if(count_negative==0){//3.没有负数
            if(count_zero!=0){
                //3.1 有零。不用改了。
            }
            else{//3.2 没有零。
                if(k%2==0){//偶数次,变回自己
                    //不用改了
                }
                else{
                    //修改最小的正数
                    if(count_positive!=0){
                        nums[first_positive]=-nums[first_positive];
                    }
                }
            }
        }
        int sum=0;
        for(int num:nums)
            sum+=num;
        return sum;
    }
}
/**
把负数变成正的,下标越小越好
不想继续改变,如果有0,就改变0
把正数变成负的,下标越小越好
变k次,可以多次选择同一个下标。
 */

网上的思路

第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
第二步:从前向后遍历,遇到负数将其变为正数,同时K–
第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
第四步:求和

简洁实现

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        Arrays.sort(nums);
        int len=nums.length;
        //首先对所有负数、0进行取反
        int i=0;
        for(i=0;i<len&&k>0&&nums[i]<=0;i++){
            nums[i]=-nums[i];
            k--;    
        }
        //负数和0都用完了,i是正数了
        //还有反转次数,并且是奇数。必须要取反一次了。
        if(k>0&&k%2!=0){
            //下标没越界
            if(i<len){
                //第一个正数取反或者前面一个数(最后一个负数或者0)取反
                if(i-1>=0&&nums[i-1]<nums[i]){//前面一个数绝对值更小
                    nums[i-1]=-nums[i-1];
                }
                else{//当前正数的绝对值更小
                    nums[i]=-nums[i];
                }
            }
            //下标越界了,只能最后一个取反
            else{
                nums[i-1]=-nums[i-1];
            }
        }
        //计算结果,最大的总和
        int sum=0;
        i=0;
        for(i=0;i<len;i++){
            sum+=nums[i];
        }
        return sum;
    }
}
/**
将负数替换为正数
负数个数不够了?
多出的是偶数次:负数重复多次?变化偶数次等于没变化。
多出的是奇数次,让绝对值最小的那个数变一次。
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值