动态规划简单题小结

198、House Robber

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example 1:

Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
             Total amount you can rob = 1 + 3 = 4.

Example 2:

Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.

题目大概的意思是一个数组里面求不连续的最大和。我们先拿一个简单的例子来分析一下,比如说nums为{3, 2, 1, 5},那么我们来看我们的dp数组应该是什么样的,首先dp[0]=3没啥疑问,再看dp[1]是多少呢,由于3比2大,所以我们抢第一个房子的3,当前房子的2不抢,所以dp[1]=3,那么再来看dp[2],由于不能抢相邻的,所以我们可以用再前面的一个的dp值加上当前的房间值,和当前房间的前面一个dp值比较,取较大值当做当前dp值,所以我们可以得到状态转移方程dp[i] = max(num[i] + dp[i - 2], dp[i - 1]), 由此看出我们需要初始化dp[0]和dp[1],其中dp[0]即为num[0],

class Solution {
    public int rob(int[] nums) {
        if(nums.length == 0)
            return 0;
        if(nums.length == 1)
            return nums[0];
        //dp数组用来存当前最大值。
        int[] dp = new int[nums.length];
    
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0],nums[1]);
        for(int i = 2; i < nums.length; i++)
        {
            dp[i] = Math.max(nums[i]+dp[i-2], dp[i-1]);
        }
        
        return dp[nums.length - 1];
    }
}

53、Maximum Subarray

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

思路:对于这种连续的求最大最小。要有两个东西,一个是保存最大值的,一个是记录起始点的。

class Solution {
    public int maxSubArray(int[] nums) {
        
        if(nums.length <= 0)
            return 0;
        
        //记录最大值
        int greatResult = nums[0];
        //记录起始点
        int result = nums[0];
        for(int i = 1; i < nums.length; i++)
        {
          /*  //当前面的结果集是小于0的,说明这一段都没用,重新选起始点
            if(result <= 0)
                result = nums[i];
            else
                //否则加上下一个数判断是否大于这个数
                result += nums[i];
            //用一个数来存最大值
            */
            //如果是加上当前位置的值不会大于当前这个位置的值。说明前面这一段相加没用,重新找起始点
            result = result+nums[i];
            if(result < nums[i])
                result = nums[i];                  
            greatResult = Math.max(greatResult, result);
                
        }
        return greatResult;
       }
  }

121、 Best Time to Buy and Sell Stock

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Note that you cannot sell a stock before you buy one.

Example 1:

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
             Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

这道题跟上面那道题类似,也是要记录起始点和增值。

class Solution {
    public int maxProfit(int[] prices) {
        
        int max = 0;
        if(prices.length <= 0)
            return max;
        int start = prices[0];
        for(int i = 1; i < prices.length; i++)
        {
            //用来记录最小值
            if(prices[i] < start)start = prices[i];
            else 
                //用来判断最大利润
                max = Math.max(max,prices[i] - start);
        }
        
        return max;
    }
}

70. Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Note: Given n will be a positive integer.

Example 1:

Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps

Example 2:

Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step

思路:斐波那契数列

class Solution {
    public int climbStairs(int n) {
        
        int one = 0;
        int two = 1;
        while(n-- >= 0)
        {
            two += one;
            one = two - one;
        }
        return one;
    }
}

总结:动态规划主要还是要找出它的迭代规律。是否可以从小规模的最值问题再来拓展至整个大的。还有就是找出它的转移方程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章