ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

动态规划-2-1

2020-02-01 09:00:53  阅读:432  来源: 互联网

标签:return int Stairs memo climbStairs 动态 规划 public


最大子序和

  1. public int crossSum(int[] nums, int left, int righ, int p){
        if(left == right) return nums[left];
        
        int leftSubsum = Integer.MIN_VALUE;
        int currSum = 0;
        for(int i=p;i > left -1; --i){
            currSum += nums[i];
            leftSubsum = Math.max(leftSubsum, currSum);
        }
        
        int rightSubsum = Integer.MIN_VALUE;
        currSum = 0;
        for(int i = p +1;i<right + 1;++i){
    		currSum += nums[i];
            rightSubsum = Math.max(rightSubsum, currSum);
        }
        return leftSubsum + rightSubsum;
    }
    
    public int helper(int[] nums, int left, int right){
        if(left == right) return nums[left];
        
        int p = (left + right) / 2;
        
        int leftSum = helper(nums, left, p);
        int rightSum = helper(nums, p + 1, right);
        int crossSum = crossSum(nums, left, right, p);
        
        return Math.max(Math.max(leftSum, rightSum), crossSum);
    }
    
    public int maxSubArray(int[] nums){
        return helper(nums, 0, nums.lenght - 1);
    }

    爬楼梯

    每步只能爬1或2个台阶,总共多少种方法。

    1. 暴力法:把所有可能爬的阶数进行组合,也就是1和2.

    2. climbStairs(i,n)=(i+1,n)+climbStairs(i+2,n) climbStairs(i,n) = (i+1, n) + climbStairs(i+2,n) climbStairs(i,n)=(i+1,n)+climbStairs(i+2,n)

其中i定义了当前阶数,而n定义了目标阶数。

public class Solution{
    public int climbStairs(int n){
        climb_Stairs(0,n);
    }
    
    public int climb_Stairs(int i, int n){
        if(i > n){
            return 0;
        }
        if(i == n){
            return 1;
        }
        return climb_Stairs(i+1, n) + climb_Stairs(i+2, n);
    }
}
  1. 记忆化递归

  2. 思路:把每一步的结果存储在memo数组之中,当函数每次被调用,我们就直接从memo数组中返回结果。在memo数组的帮助下,可以得到一个修复的递归树,其大小减小到n。

  3. public class Solution{
        public int climbStairs(int n){
            int memo[] = new int[n + 1];
            return climb_Stairs(0,n,memo);
        }
        public int climb_Stairs(int i, int n, int memo[]){
            if(i > n){
                return 0;
            }
            if(i == n){
                return 1;
            }
            if(memo[i] > 0){
                return memo[i];
            }
            memo[i] = climb_Stairs(i + 1, n, memo) + climb_Stairs(i + 2, n, memo);
            return memo[i];
        }
    }
  4. 时间和空间复杂度为:O(n)

    1. 动态规划

    2. 思路:可以被分解为一些包含最优子结构的子问题。即他的最优解可以从其子问题的最优解来有效构建。

      i阶可以由以下的两种方法得到:
      	1. 在第(i-1)阶后向上爬一阶
      	2. 在第(i - 2)阶后向上爬2阶。
      public class Solution{
          public int climbStairs(int n){
              if(n == 1){
                  return 1;
              }
              int[] dp = new int[n + 1];
              dp[1] = 1;
              dp[2] = 2;
              for(int i = 3;i <= n; i++){
                  dp[i] = dp[i-1]+dp[i-2];
              }
              return dp[n];
          }
      }

      方法四:斐波那契数,

      public class Solution{
          public climbStairs(int n){
              if(n==1){
                  return 1;
              }
              int first = 1;
              int second = 2;
              for(int i=3;i<=n;i++){
                  int third = first + second;
                  first = second;
                  second = third;
              }
              return second;
          }
      }

      方法五:Binets方法,两种方式初始化数组,第一种,将斐波那契数列的初始项修改为2和1来代替原来的1和0. 第二种,使用相同的初始化矩阵Q并使用result = Qn[0,0]得到最后的结果。

      public class Solution{
          public int climbStairs(int n){
              int[][] q = {{1,1},{1,0}};
              int res = pow(q, n);
              return res[0][0];
          }
          public int[][] pow(int[][] p, int n){
              int[][] ret = {{1,0},{0,1}};
              while(n > 0){
                  if((n & 1) == 1){ //判断n是否是奇数
                      ret = multiply(ret,a);
                  }
                  n >>= 1;//n的二进制数向右移动一位
                  a = multiply(a, a);
              }
              return ret;
          }
          public int[][] multiply(int[][] a, int[][] b){
              int[][] c = new int[2][2];
              for(int i=0; i<2;i++){
                  for(int j=0;j<2;j++){
                      c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];
                  }
              }
              return c;
          }
      }

      不同路径

      这是个杨辉三角形,每个位置的路径=该位置左边的路径+该位置上边的路径。

      二维数组的动态规划

      class Solution{
          public int uniquePaths(int m, int n){
              int[][] dp = new int[m][n];
              for(int i=0;i<m;i++) dp[0][i]=1;
              for(int j=0;j<n;j++) dp[j][0]=1;
              for(int i=1;i<m;i++){
                  for(int j=1;j<n;j++){
                      dp[i][j] = dp[i-1][j] + dp[i][j-1];
                  }
              }
              return dp[m-1][n-1];
          }
      }

      空间压缩

      public static int uniquePaths(int m, int n){
          if(m<=0||n<=0){
              return 0;
          }
          int less = Math.min(m,n);
          int more = Math.max(m,n);
          
          int[] dp = new int[less];//空间压缩,就是利用了dp暂存上一轮的值,在这一次的赋值中循环利用第一行或第一列的值都是1,因为第一行的路径只能是从左侧走过来。
          Arrays.fill(dp,1);
          
          for(int i=1;i<more;i++){//转换成了一位数组
              for(int j=1;j<less;j++){
                  dp[j] = dp[j-1] + dp[j];
              }
          }
          return dp[less-1];
      }
jjxwj 发布了46 篇原创文章 · 获赞 13 · 访问量 1万+ 私信 关注

标签:return,int,Stairs,memo,climbStairs,动态,规划,public
来源: https://blog.csdn.net/qq_31900497/article/details/104130215

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有