動態規劃-數組

leetcoe 面試題 16.17. 42.連續數列最大和

題目
給定一個整數數組,找出總和最大的連續數列,並返回總和。
示例

輸入: [-2,1,-3,4,-1,2,1,-5,4]
輸出: 6
解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。

代碼

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size() == 0) return  0;
        vector<int> dp(nums.size());
        dp[0] = nums[0];
        int res = dp[0];
        for(int i = 1; i < nums.size(); i++){
            dp[i] = dp[i-1] > 0 ? (dp[i-1]+nums[i]) : nums[i];
            res = max(res, dp[i]);
        }
        return res;

    }
};

leetcode.1143. 最長公共子序列

題目
給定兩個字符串 text1 和 text2,返回這兩個字符串的最長公共子序列的長度。

一個字符串的 子序列 是指這樣一個新的字符串:它是由原字符串在不改變字符的相對順序的情況下刪除某些字符(也可以不刪除任何字符)後組成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。兩個字符串的「公共子序列」是這兩個字符串所共同擁有的子序列。

若這兩個字符串沒有公共子序列,則返回 0

示例

輸入:text1 = "abcde", text2 = "ace" 
輸出:3  
解釋:最長公共子序列是 "ace",它的長度爲 3。

代碼

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int m = text1.size(), n = text2.size();
        int dp[m+1][n+1];
        memset(dp, 0, sizeof dp);
        for(int i = 0; i <= m; i++) dp[i][0] = 0;

        for(int i = 0; i <= n; i++) dp[0][i] = 0;

        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(text1[i] == text2[j])
                    dp[i+1][j+1] = dp[i][j]+1;
                else
                    dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j]);
            }
        }
        return dp[m][n];



    }
};

leetcode. 300最長上升子序列

題目
給定一個無序的整數數組,找到其中最長上升子序列的長度。
示例

輸入: [10,9,2,5,3,7,101,18]
輸出: 4 
解釋: 最長的上升子序列是 [2,3,7,101],它的長度是 4。

代碼

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int len = nums.size();
        if(len == 0)
            return 0;
         int dp[len];
        for(int i = 0; i < len; i++)
        {
            dp[i] = 1;
        }
        for(int i = 1; i < len; i++)
        {
            
            for(int j = 0; j < i; j++)
            {
                if(nums[i] > nums[j])
                {
                    
                    dp[i] = max(dp[i],dp[j]+1);
                }
                
            }
            
        }
        
        int maxLen = 0;
        for(int i = 0; i < len; i++)
        {
            maxLen = max(maxLen,dp[i]);
        }
        return maxLen;
        
    }
};

數組和湊數字

題目
一個數組都爲正數,可以離散選擇數組中的數字,判斷能夠湊成給定SUM值。
示例

輸入:[3,2,7,9],10
輸出:false

思路
先寫遞歸函數

bool process(int arr[], int i, int sum, int value){
	if(i == arr.size()){
		return  value ==  sum;
	}else
		return process(arr, i+1, sum, value) || process(arr, i+1, sum+arr[i], value);
}

對於數組的數字,選擇要還是不要。
dp設計爲一個二維數組,行範圍爲i 的範圍,表示每一個數組位置。列範圍爲數組和的範圍, 如例子中爲 0- 10,因爲都是正數,多了沒用。
0 1 2 · · · · · · · · · · · · · 10
1
·
·
·
·
N
這樣一個二維數組,初始化最後一行(表示i==len)dp[n][sum]一定是true, 其他都是false.

依賴關係, (i, sum)依賴於(i+1, sum)和(i+1, sum + arr[i])

得到遞推關係式

dp[i][j] = dp[i+1][j] || dp[i+1][j + arr[i]]

從最後一行得到倒數第二行,以此類推,一直往上推,得到dp[0][0] 判斷是true還是
false,就可以得到。

代碼


leetcode. 三步問題

題目
三步問題。有個小孩正在上樓梯,樓梯有n階臺階,小孩一次可以上1階、2階或3階。實現一種方法,計算小孩有多少種上樓梯的方式。結果可能很大,你需要對結果模1000000007。

示例

 輸入:n = 3 
 輸出:4
 
 輸入:n = 1000000
 輸出:746580045
 
 輸入:n = 78
 輸出:361781289
 
 提示:n的範圍 [1, 1000000]
 

模的處理做不好。
代碼


class Solution {
public:
    int waysToStep(int n) {
        
        if(n <= 1) return 1;
        if(n == 2) return 2;
        if(n == 3) return 4;
        vector<long> dp(n, 0);
        dp[0] = 1, dp[1] = 2, dp[2] = 4;
        for(int i = 3; i < n; i++){
            dp[i] = ((dp[i-1] + dp[i-2])%1000000007 + dp[i-3])%1000000007;
            
        }      
        return (int)dp[n-1]%1000000007;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章