首页 > 编程语言 >Day 28 贪心算法 Part02

Day 28 贪心算法 Part02

时间:2024-07-30 14:40:27浏览次数:9  
标签:last target nums int Part02 28 length return Day

55. 跳跃游戏

这道题我是从后往前做的,但由于用了递归,速度会慢一些,但整体时间复杂度也是O(N)。

我的思路其实就是找到最后一个可以到达目标位置处的下标,如果不存在这样的位置,就说明最后一个位置不可达。假设找到了,我们就需要去判断找到的这个位置是否可达,此时它的可达性与最后一个位置的可达性是完全一致的(这是我这个思路最重要的点)。具体的看注释。

class Solution {
    public boolean canJump(int[] nums) {
        return findLast(nums, nums.length-1); 
    }
    public boolean findLast(int[] nums, int target){ //找到最后一个能够到达target的位置,如果没有这样的位置返回false
        if(target == 0) return true; //递归出口
        int last = target - 1;
        while(last >= 0 && nums[last] < target - last){
            last--;
        }
        if(last < 0) return false; //没有节点能到达target
        return findLast(nums, last); //如果找到了,则去判断last是否可达,如果last可达target一定可达,last不可达,target也不可达
    }
}

还是贴上一份官解的,从前往后遍历的思路也很简单,只是我当时没有想到。

class Solution {
    public boolean canJump(int[] nums) {
        int curStep = 0;
        int i = 0;
        for(; i < nums.length; i++){
            curStep--;
            curStep = Math.max(curStep, nums[i]);
            if(curStep <= 0) break;
        }
        return i >= nums.length - 1;
    }
}

45. 跳跃游戏 II

先写我自己的思路吧,代码真的很丑,调了好久才全通过了。使用cnt记录步数。从起点开始,每次在其覆盖位置内,找到下一个节点,使得覆盖范围最远。所以代码中最关键的部分就是找到这个节点。

class Solution {
    public int jump(int[] nums) {
        int cnt = 0;
        int start = 0;
        while(start < nums.length - 1){
            int maxRange = start + nums[start];
            if(maxRange >= nums.length - 1) return ++cnt;  //如果已经可以覆盖终点,直接返回
            // 找到下一个覆盖范围最远的节点
            int nextStart = start, tmpMax = maxRange; //tmpMax记录最远可达的位置
            for(int i = start+1; i <= maxRange; i++){
                if(i+nums[i] > tmpMax) { //当找到更远的位置,更新tmpMax和nextStart
                    tmpMax = i + nums[i];
                    nextStart = i;
                }
            }
            start = nextStart;
            cnt++;
        }
        return cnt;
    }
}

题解的思路真是又清楚,代码又简练啊,我的妈,差距怎么这么大。思路其实是差不多的,但是这样写出来就是非常简练。

class Solution {
    public int jump(int[] nums) {
        if(nums.length == 1) return 0;
        int curRange = 0; // 当前覆盖的最远位置
        int step = 0;
        int nextRange = 0; // 下一步覆盖最远位置
        for(int i = 0; i < nums.length; i++){
            if(curRange >= nums.length - 1) break; //如果已经覆盖了最后一个位置
            nextRange = Math.max(nextRange, i + nums[i]);
            if(curRange == i){
                curRange = nextRange;
                step++;
            }
        }
        return step;
    }
}

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

即便是简单题,我写的也是依托啊。没脸贴自己的代码了,直接放下面看到的题解。

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        // 排序,把可能有的负数排到前面
        Arrays.sort(nums);
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            // 贪心:如果是负数,而k还有盈余,就把负数反过来
            if (nums[i] < 0 && k > 0) {
                nums[i] = -1 * nums[i];
                k--;
            }
            sum += nums[i];
        }
        Arrays.sort(nums);
        // 如果k没剩,那说明能转的负数都转正了,已经是最大和,返回sum
        // 如果k有剩,说明负数已经全部转正,所以如果k还剩偶数个就自己抵消掉,不用删减,如果k还剩奇数个就减掉2倍最小正数。
        return sum - (k % 2 == 0 ? 0 : 2 * nums[0]); 
    }
}

标签:last,target,nums,int,Part02,28,length,return,Day
From: https://www.cnblogs.com/12sleep/p/18332329

相关文章

  • Solution - Atcoder AGC028B Removing Blocks
    因为贡献的方法是相加,一种想法就是拆开,对每一项单独贡献。不难发现这题目中的贡献其实只涉及到两点之间。即删除\(x\)时\(y\)也产生了贡献。考虑这个贡献会在多少种排列中出现。令\(d=|x-y|+1\),即\(x,y\)中的点数。能发现排列需要满足除\(x\)外的\(d-1\)......
  • LeetCode-day30-2961. 双模幂运算
    LeetCode-day30-2961.双模幂运算题目描述示例示例1:示例2:思路代码题目描述给你一个下标从0开始的二维数组variables,其中variables[i]=[ai,bi,ci,mi],以及一个整数target。如果满足以下公式,则下标i是好下标:0<=i<variables.length((aibi%10)ci)......
  • Day 23 - 模拟赛
    百万富翁的第二次实验题目描述马克吐温有一本非常著名的小说《百万英镑》,这本小说中主角最后归还了百万英镑给两位富翁。但结果就是两位富翁依然有无穷的问题需要进行社会实验,于是,他们打算进行第二次社会实验。那就是不同财富值的人在一场舞会上会发生什么事情。为了满足自己的......
  • APP逆向 day24unidbg上
    一.前言今天开始讲app逆向最后一个也是最重要的unidbg,这已经是从初级进阶到中级的了,我会讲unidbg,讲三节课,分为上中下来和大家讲(由简单到难逐步),这节课主要是和大家讲unidbg的介绍并且会结合之前讲的简单案例来让大家理解,如果过程中不太记得之前的位置定位,可以去看之前的课程,在......
  • day11 Java基础——基本运算符
    day11Java基础——基本运算符小技巧:CTRL+D复制当前行到下一行例1:packageoperator;publicclassDemo01{publicstaticvoidmain(String[]args){//二元运算符inta=10;intb=20;intc=25;intd=25;......
  • 代码随想录day14 || 226 翻转二叉树,101 对称二叉树, 104 二叉树的最大深度, 111 二叉树
    226翻转二叉树funcinvertTree(root*TreeNode)*TreeNode{ //思考,广度优先遍历,对于每一层,翻转其左右子节点 ifroot==nil{ returnnil } queue:=list.New() queue.PushBack(root) size:=1//存储每一层的节点个数 forqueue.Len()>0{ varcountint ......
  • Day14 二叉树Part2 递归的应用(二叉树相关)
    任务226.翻转二叉树给你一棵二叉树的根节点root,翻转这棵二叉树,并返回其根节点。思路逻辑上,我们知道用递归遍历一棵树,一定会遍历每个节点。因此在遍历的过程中处理即可。考虑递归基,即当节点为空时直接返回。考虑单层递归,为了反转二叉树,如何处理当前节点呢?即如何反转以当......
  • 代码随想录算法训练营第28天 | 贪心进阶
    2024年7月30日题122.买卖股票的最佳时机II上涨就买,下跌就不买。classSolution{publicintmaxProfit(int[]prices){intsum=0;for(inti=1;i<prices.length;i++){sum+=prices[i]-prices[i-1]>0?prices[i]-prices[i-1]:0;......
  • 【2024-07-28】连岳摘抄
    23:59命运总是不如人愿。但往往是在无数的痛苦中,在重重的矛盾和艰辛中才使人成熟起来。                                                 ——路遥你瞧不起你刚刚得......
  • python三天速成记(看完你就会)day3 满满干货~
    续上文啦~EXCEL表的操作上一篇文章讲了怎么读取和操作txt和csv文档,但其实我们生活中还有一个常用的文本格式那就是excel文件,特别是在对大量数据进行处理的时候。excel文件的用处和广泛。其实在python中有很多库可以处理excel文件,但是本文主要介绍使用最实用最广泛的库pan......