動態規劃簡單題小結

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;
    }
}

總結:動態規劃主要還是要找出它的迭代規律。是否可以從小規模的最值問題再來拓展至整個大的。還有就是找出它的轉移方程。

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