• 【leetcode】 55 跳跃游戏


    一开始的思路是,用一个二维数组 dp[i][j]  记录从位置 i 是否可以到达位置 j ,然后再遍历从最后一列起从后往前遍历每一列,如果这一列存在 1 则说明该列对应的下标是可达的,继续遍历前一列,如果某一列的值全部为0,说明该列对应的位置是不可达的,整体不可达,返回false,思来想去,觉得这个思路应该没有太大的问题,可能内存不能达到要求,果然,提交后,用例只跑到了第70个,内存超出限制了。

    class Solution {
        public boolean canJump(int[] nums) {
              // n 是行,m是列
            int n = nums.length-1,m = nums.length;
            int dp[][] = new int[n][m];
            // 因为最后一个位置是终点,所以i从0到n-1个位置即可
            for (int i = 0; i < n; i++) {
                for (int j = i+1; j <m; j++) {
                    // 某个位置i上加上该位置上的值nums[i]如果大于等于j,则说明i上可以到达j
                    dp[i][j] = i+nums[i]>=j?1:0;
                    if (dp[i][j]==0)
                        break;
                }
            }
    
            // 从最后一列开始,遍历每一列的每一个行元素,求该列元素的 |
            for (int i = m-1; i >0 ; i--) {
                int result = 0;
                for (int j = 0; j < n; j++) {
                    result |= dp[j][i];
                }
                if (result==0){
                    return false;
                }
            }
    
          return true;
        }
    }

     解析:

    当 i = 0 时,nums[0] = 2 ,说明在 i= 0的位置可以移动2个单位,因此 当 j = 1 , 2 时 dp[i][j] =1;

    当 i= 1 时,nums[1] = 1,说明在 i= 1的位置可以移动1一个单位,因此 dp[1][2] = 1

    以此类推,最后得到一个dp二维数组

    接着从最后一列往前遍历,如果某一列的值全部为0,说明该列对应的下标是不可达的。如下

     下标为3时,该列的值全部为0,说明下标为3这个位置不能达到。

    (ps:这只是一个不成熟的思考方向,看看就好,用例只通过了70个,内存已经超出限制了,也不知道没有内存的限制下,这个思路是否正确。)


    后来想了想,换了一种写法

    class Solution {
        public boolean canJump(int[] nums) {
             int n = nums.length-1,end = nums.length-1;
            for (int i = n-1; i >=0 ; --i) {
                if (i+nums[i]>=end)
                    end = i;
            }
            return end==0;
        }
    }

     初始时,end = 5,for循环从数组倒数第二个位置(i=4)往前遍历

    此时有 i + nums[i] = 4+1 =5 >=end,因此在接下来的循环中,终点不再是5,而是 end = i= 4

    (因此此时if条件成立,说明 在 位置 i = 4 时,是可以移动到终点end = 5 的,那么接下来只要验证,i = 4前面的位置,可以移动到  4 这个位置即可)

    【如果终点end在某个位置 i 时 被验证可达,则接下来只要验证 i 之前的位置是否可以达到 i (end=i) 即可】

    如果条件不成立,则终点不变,i 继续往前。

    最后for循环结束后,如果end = 0 说明可以到达,否则不行。

    再有这个例子

     i从4开始往前遍历,当 i = 4、3、2、1 时都有 i+nums[i] <end = 5

    当 i = 0时有 i +nums[0] = 5 >=end;

    此时应该修改 end = i 即end = 0;

     if i + nums[i] >= end
           继续验证
                i-1 +nums[i-1] >= i (end=i)
        else
            i-1 +nums[i-1] >= end
  • 相关阅读:
    xcode快捷键大全(转)
    a 和an 的用法区别
    如何在lion系统下安装Xcode 3.2.x版本
    xcode3.2.6升级至4.0.2经验加教训总结(转)
    堆与栈的关系与区别(转)
    [点评]谷歌发布Android 2.3 点评八大亮点
    浅谈关于nil和 null区别及相关问题(转)
    ObjectiveC中的继承与复合技术(转)
    MyEclipse 8.0.0 in Fedora 12
    如何判断两个链表相交及找到第一个相交点
  • 原文地址:https://www.cnblogs.com/Guhongying/p/15361021.html
Copyright © 2020-2023  润新知