Day67(贪心算法)

45、跳跃游戏 II

给你一个非负整数数组 nums ,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

假设你总是可以到达数组的最后一个位置。

思路:只要考虑每一跳所能达到的最远位置就行了,也就是每次都选择最远可达的点,reach是当前需要进行跳跃的右界限(在界限范围内只算一步【没有更新界限的情况下】),nextReach是下一次跳跃的右界限,nextReach的值一直动态更新,以保证每次跳跃都是最远的

i表示遍历数组的时候,在界限reach内来查找下一个界限nextreach的范围【即:查找界限内最大的值】当i==reach,表示在界限内已经找到了最大的值了,这时候step++,且更新界限的新的范围【reach=nextreach】。如果判断下一界限的范围能够覆盖数组最后一个索引,这时候就return step+1.

class Solution {
    public int jump(int[] nums) {
        //只要考虑每一跳所能达到的最远位置就行了,也就是每次都选择最远可达的点,
        //reach是当前需要进行跳跃的右界限,nextReach是下一次跳跃的右界限,
        //nextReach的值一直动态更新,以保证每次跳跃都是最远的
        if(nums.length == 1) return 0;
        int reach = 0;
        int nextreach = nums[0];
        int step = 0;
        for(int i = 0;i<nums.length;i++){
            nextreach = Math.max(i+nums[i],nextreach);
            if(nextreach >= nums.length-1) return (step+1);
            if(i == reach){
                step++;
                reach = nextreach;
            }
        }
        return step;
    }
}

728、自除数(每日一题,不是贪心算法)

 重新复习获取一个数(不知道他是几位数)的每一个个数的值

class Solution {
    public List<Integer> selfDividingNumbers(int left, int right) {
        List<Integer>list=new ArrayList<>();
        for(int i=left;i<=right;i++){
            if(isValid(i)){
                list.add(i);
            }
        }
        return list;
    }

    public boolean isValid(int i){
        int temp=i;
        while(temp>0){
            int digit=temp%10;//防止digit为0
            if(digit==0||i%digit!=0){//因为要判断【i%i的每个个数】是否为0,所以i不能变,而每次i都要除10才能算出个位数/十位数/百位数,所以这时候要用临时变量来替代i。
                return false;
            }
            temp=temp/10;
        }
        return true;
    }
}

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

给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

  • 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。

重复这个过程恰好 k 次。可以多次选择同一个下标 i

以这种方式修改数组后,返回数组 可能的最大和

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
       Arrays.sort(nums);
       int sum=0;
       int index=-1;//查找数组中是否有0的索引

       //为了最大,把数组中的负数变成正数
       for(int i=0;i<nums.length;i++){
           if(nums[i]<0&&k>0){
               nums[i]=-nums[i];
               k--;//将 nums[i] 替换为 -nums[i] ,要执行k次
           }

           if(nums[i]==0){
               index=i;
           }
       }

        //判断数组中是否有0的存在
       if(index>=0){
           while(k>0){
               nums[index]=-nums[index];
               k--;
           }
       }
       
       //经过上述操作后只剩下正数了,那么重新排序
        Arrays.sort(nums);
       
       //判断把负数和0都替换后,还要执行多少次
       for(int i=0;i<k;i++){
           nums[0]=-nums[0];
       }

       for(int num:nums){
           sum+=num;
       }

       return sum;
    }
}

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值