zoukankan      html  css  js  c++  java
  • leetcode55 jumpGame贪心算法

    上题目:

      解空间明确,一个从 nums[0] 开始辐射出去的树状解空间。首先暴力搜索一下,暴力搜索解法:

        public final boolean canJump(int[] nums) {
            if(nums==null){return false;}
            int length=nums.length;
            return jump(nums,length,0);
        }
    
        public final boolean jump(int[] nums,int length,int current){
            if(current==length-1){
                return true;
            }
            if(current>length-1){
                return false;
            }
            boolean re=false;
            int currentSteps=nums[current];
            for(int i=1;i<=currentSteps;i++){
                re=re||jump(nums,length,current+i);
            }
            return re;
        }

      解的过程中我们发现,回归过程是自底向上的,在回归的过程中,有大量的节点出现了重复计算,可考虑缓存避免重复计算。缓存搜索:

        public final boolean canJump(int[] nums) {
            if(nums==null){return false;}
            int length=nums.length;
            int[] cache=new int[length];
            return jump(nums,length,0,cache);
        }
    
        public final boolean jump(int[] nums,int length,int current,int[] cache){
            if(current==length-1||cache[current]==1){return true;}
            if(current>length-1||cache[current]==-1){return false;}
            boolean re=false;
            int currentSteps=nums[current];
            for(int i=1;i<=currentSteps;i++){
                if(jump(nums,length,current+i,cache)){
                    re=true;
                    break;
                }
            }
            cache[current]=re?1:-1;
            return re;
        }

      缓存计算定义好后,考虑避免递归带来的栈帧释放创建的开销,逆推缓存优化为动态规划解法:

        public final boolean dpJump1(int[] nums) {
            if (nums == null) {
                return false;
            }
            int length = nums.length;
            int[] cache = new int[length];
            int goodNode = 0;
            for (int i = length - 1; i >= 0; i--) {
                int currentStep = nums[i];
                if (currentStep + i >= (length - 1)) {
                    goodNode = i;
                    cache[i] = 1;
                    continue;
                }
                for (int j = i + currentStep; j >= i; j--) {
                    if (cache[j] == 1) {
                        cache[i] = 1;
                        break;
                    }
                }
                printNums(cache);
            }
            return cache[0] == 1 ? true : false;
        }

      动态规划的过程中牵扯到两层 for 循环,内层的 for 循环可以使用贪心算法优化,以局部最优解获得全局最优解,我们只需要找到互动范围内最近的可到达终点的 goodNode 就可以了。贪心算法:

        //贪心
        public final boolean dpJump(int[] nums) {
            if (nums == null) {
                return false;
            }
            int length = nums.length;
            int[] cache = new int[length];
            int goodNode = 0;
            for (int i = length - 1; i >= 0; i--) {
                int currentStep = nums[i];
                if (currentStep + i >= (length - 1)) {
                    goodNode = i;
                    cache[i] = 1;
                    continue;
                }
                if (goodNode != 0 && (i + currentStep) >= goodNode) {
                    goodNode = i;
                    cache[i] = 1;
                }
                printNums(cache);
            }
            return cache[0] == 1 ? true : false;
        }
  • 相关阅读:
    Object-C,NSSet,不可变集合
    NYIST 860 又见01背包
    NYIST 1070 诡异的电梯【Ⅰ】
    HDU 1542 Atlantis
    HDU 4756 Install Air Conditioning
    CodeForces 362E Petya and Pipes
    HDU 4751 Divide Groups
    HDU 3081 Marriage Match II
    UVA 11404 Palindromic Subsequence
    UVALIVE 4256 Salesmen
  • 原文地址:https://www.cnblogs.com/niuyourou/p/12643634.html
Copyright © 2011-2022 走看看