leetcode 动态规划系列一 java解题

121. Best Time to Buy and Sell Stock easy题目

 public int maxProfit(int[] prices) {
        int buy=Integer.MAX_VALUE;
        int maxpro=0;
        for(int i=0;i<prices.length;i++){
            buy=Math.min(prices[i],buy);
            maxpro=Math.max(maxpro,prices[i]-buy);
        }
        return maxpro;
    }

746. Min Cost Climbing Stairs

当前的花费取决于前面一个或两个的花费

public int minCostClimbingStairs(int[] cost) {
        int dp[]=new int[1002];
        dp[0]=cost[0];
        dp[1]=cost[1];
        int n=cost.length;
        for(int i=2;i<n;i++){
            dp[i]=cost[i]+Math.min(dp[i-1],dp[i-2]);
        }
        return Math.min(dp[n-1],dp[n-2]);
    }

70. Climbing Stairs

思路:第i个的方法取决于第i-1个和第i-2个台阶的组合数

    int climbStairs(int n) {
       if (n == 1)
            return 1;
        if (n < 1)
            return 0;
        
        int dp[n];
        dp[0] = 1;
        dp[1] = 2;

        for (auto i = 2; i < n; i++)
            dp[i] = dp[i - 1] + dp[i - 2];

        return dp[n-1];
    }

53. Maximum Subarray

思路:最大连续数组,cursum初始值是0,每遍历一个数字,比较cursum+num和num中的最大值,如果cursum为负数,则从头开始,将最大的cursum存入res中

对于相加的情况,只要能够处理局部最大和全局最大之间的关系即可

local[i + 1] = Max(local[i] + A[i], A[i]);

global[i + 1] = Max(local[i + 1], global[i]);

    public int maxSubArray(int[] nums) {
        int res=Integer.MIN_VALUE;
        int cursum=0;
        for(int num:nums){
            cursum=Math.max(cursum+num,num);
            res=Math.max(cursum,res);
        }
        return res;
    }

152. Maximum Product Subarray

思路:最大子数组的乘机。其中 f[i] 表示子数组 [0, i] 范围内并且一定包含 nums[i] 数字的最大子数组乘积,g[i] 表示子数组 [0, i] 范围内并且一定包含 nums[i] 数字的最小子数组乘积,初始化时 f[0] 和 g[0] 都初始化为 nums[0],其余都初始化为0。那么从数组的第二个数字开始遍历,那么此时的最大值和最小值只会在这三个数字之间产生,即 f[i-1]*nums[i],g[i-1]*nums[i],和 nums[i]。所以用三者中的最大值来更新 f[i],用最小值来更新 g[i],然后用 f[i] 来更新结果 res 即可

    public int maxProduct(int[] nums) {
        int n=nums.length;
        int f[]=new int[n];
        int g[]=new int[n];
        f[0]=nums[0];
        g[0]=nums[0];
        int res=nums[0];
        for(int i=1;i<n;i++){
            f[i]=Math.max(Math.max(f[i-1]*nums[i],g[i-1]*nums[i]),nums[i]);
            g[i]=Math.min(Math.min(f[i-1]*nums[i],g[i-1]*nums[i]),nums[i]);
            res=Math.max(res,f[i]);
        }
        return res;
    }

198. House Robber

思路:递推公式dp[i] = max(num[i] + dp[i - 2], dp[i - 1]), 由此看出我们需要初始化dp[0]和dp[1],其中dp[0]即为num[0],dp[1]此时应该为max(num[0], num[1])。

 public int rob(int[] nums) {
      int n=nums.length;
        if(n==0)return 0;
        if(n==1)return nums[0];
        int dp[]=new int[n];
        dp[0]=nums[0];
        dp[1]=Math.max(nums[0],nums[1]);
        for(int i=2;i<n;i++){
            dp[i]=Math.max(dp[i-2]+nums[i],dp[i-1]);
        }
        return Math.max(dp[n-1],dp[n-2]);
    }

213. House Robber II

198的升级版本,需要去掉头尾,分成两种情况,调用198的代码即可

public int subrob(int[] nums,int s,int e) {
        int n=e-s+1;
        int dp[]=new int[n];
        dp[0]=nums[s];
        dp[1]=Math.max(nums[s],nums[s+1]);
        for(int i=2;i<n;i++){
            dp[i]=Math.max(dp[i-2]+nums[s+i],dp[i-1]);
        }
        return Math.max(dp[n-1],dp[n-2]);
    }
    public int rob(int[] nums) {
        int n=nums.length;
        if(n==0)return 0;
        if(n==1)return nums[0];
        if(n==2)return Math.max(nums[0],nums[1]);
        return Math.max(subrob(nums,0,nums.length-2),subrob(nums,1,nums.length-1));
    }
发布了192 篇原创文章 · 获赞 27 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/lovely_girl1126/article/details/103496698