zoukankan      html  css  js  c++  java
  • LeetCode 55. 跳跃游戏

    我的LeetCode:https://leetcode-cn.com/u/ituring/

    我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii

    LeetCode 55. 跳跃游戏

    题目

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

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

    判断你是否能够到达最后一个位置。

    示例 1:

    输入: [2,3,1,1,4]
    输出: true
    解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
    

    示例 2:

    输入: [3,2,1,0,4]
    输出: false
    解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
    

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/jump-game
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解题思路

    贪心算法:一种是从前往后贪,另一种是从后往前贪;

    思路1-从前往后贪心

    步骤:

    1. 初始最远可达为end=0,若i在end范围内,则更新end的最远可达为Math.max(end, i + nums[i]),否则直接返回不可达(若i都不可达,则i之后的更不可达);
    2. 一旦end>=数组长度则说明可达并返回,否则最终返回不可达;

    算法复杂度:

    • 时间复杂度: $ {color{Magenta}{Omicronleft(N ight)}} $
    • 空间复杂度: $ {color{Magenta}{Omicronleft(1 ight)}} $

    思路2-从后往前贪心

    步骤:

    1. 反向思考,从最后一个位置算起,若当前位置可达:i + nums[i] >= i;
    2. 则更新i为新的待检测是否可达点,其实就是不断向0收敛i,若最终收敛至0则可达,否则不可达;

    算法复杂度:

    • 时间复杂度: $ {color{Magenta}{Omicronleft(N ight)}} $
    • 空间复杂度: $ {color{Magenta}{Omicronleft(1 ight)}} $

    算法源码示例

    package leetcode;
    
    /**
     * @author ZhouJie
     * @date 2020年2月20日 下午7:50:49 
     * @Description: 55. 跳跃游戏
     *
     */
    public class LeetCode_0055 {
    
    }
    
    class Solution_0055 {
    	/**
    	 * @author: ZhouJie
    	 * @date: 2020年2月20日 下午8:19:05 
    	 * @param: @param nums
    	 * @param: @return
    	 * @return: boolean
    	 * @Description: 1-最开始的思路写的,优化后为方法3--canJump_3
    	 *
    	 */
    	public boolean canJump_1(int[] nums) {
    		if (nums == null || nums.length < 2) {
    			return true;
    		}
    		int len = nums.length;
    		for (int i = 0; i < len;) {
    			if (nums[i] >= len - 1 - i) {
    				return true;
    			}
    			int k = i + 1, subStemp = 0, temp;
    			for (int j = i + 1; j < i + nums[i] + 1; j++) {
    				temp = j + nums[j];
    				if (temp > subStemp) {
    					subStemp = temp;
    					k = j;
    				} else if (temp == subStemp && nums[j] >= nums[k]) {
    					k = j;
    				}
    			}
    			if (subStemp == 0) {
    				return false;
    			}
    			i = k;
    		}
    		return false;
    	}
    
    	/**
    	 * @author: ZhouJie
    	 * @date: 2020年2月20日 下午8:19:17 
    	 * @param: @param nums
    	 * @param: @return
    	 * @return: boolean
    	 * @Description: 2-从后向前检测
    	 *
    	 */
    	public boolean canJump_2(int[] nums) {
    		if (nums == null || nums.length < 2) {
    			return true;
    		}
    		int check = nums.length - 1;
    		for (int i = check; i > -1; i--) {
    			// 若该位置可达,则更新为新的可达位置,即把i值往最小收敛,为0即为可达
    			if (i + nums[i] >= check) {
    				check = i;
    			}
    		}
    		return check == 0;
    	}
    
    	/**
    	 * @author: ZhouJie
    	 * @date: 2020年4月17日 下午8:25:56 
    	 * @param: @param nums
    	 * @param: @return
    	 * @return: boolean
    	 * @Description: 3-对方法1的优化,其实方法1的内循环就是贪心思想,但是这个处理可以提出来并到外循环,避免二次for
    	 *
    	 */
    	public boolean canJump_3(int[] nums) {
    		if (nums == null || nums.length < 2) {
    			return true;
    		}
    		int len = nums.length;
    		// 可到达的最远位置
    		int end = 0;
    		for (int i = 0; i < len; i++) {
    			// 若当前位置可达
    			if (i <= end) {
    				// 更新最远可达位置,若可达终点直接return
    				end = Math.max(end, i + nums[i]);
    				if (end >= len - 1) {
    					return true;
    				}
    			} else {
    				return false;
    			}
    		}
    		return false;
    	}
    }
    
  • 相关阅读:
    2017NOIP游记 (格式有点炸)
    Qtree3
    [P2769] 猴子上树
    [Usaco2005 Dec]Cleaning Shifts 清理牛棚
    [NOIP2014] 解方程
    [ZJOI2012] 灾难
    [洛谷P3941] 入阵曲
    [SCOI2009] 最长距离
    [JLOI2011] 飞行路线
    虚拟化数电底层
  • 原文地址:https://www.cnblogs.com/izhoujie/p/12722650.html
Copyright © 2011-2022 走看看