动态规划类

子序列的最大和
LeetCode 53

给定一个整数数组nums,找到具有最大总和并返回其总和的连续子数组(包含至少一个数字)。

例:

输入: [ -  2,1,-3,4,-1,2,1,-5,4],
 输出: 6
 说明:  [4,-1,2,1]具有最大的和= 6。

跟进:

如果你已经找到O(n)解决方案,尝试使用分而治之的方法编写另一个解决方案,这是更微妙的。

动态规划(O(n))

public class Solution {
    public int MaxSubArray(int[] nums) {
        if(nums.Length==0){
            return 0;
        }
        int cur=nums[0];
        int res=cur;
        for(int i=1;i<nums.Length;i++){
            cur=nums[i]>(cur+nums[i])?nums[i]:(cur+nums[i]);
            res=cur>res?cur:res;
        }
        return res;
    }
}

分治法,最大子序和要么在左半部分,要么在右半部分,要么就横跨两部分(即包括左半部分的最后一个元素,和右半部分的第一个元素)。返回这三种情况的最大值即可。第三种情况,其中包括左半部分最后一个元素的情形,需要挨个往前遍历,更新最大值。包含右半部分的第一个元素的情况类似。总的时间复杂度O(nlogn)
 

public class Solution {
    public int MaxSubArray(int[] nums) {
        int left=0;
        int right=nums.Length-1;
        return divide(nums,left,right);
          
    }
    public int divide(int[] nums,int left,int right){
        if(left==right)
            return nums[left];
        int center=(left+right)/2;
        int leftmax=divide(nums,left,center);
        int rightmax=divide(nums,center+1,right);
        
        int leftBordersum=nums[center];
        int leftsum=nums[center];
        for(int i=center-1;i>=left;i--){
            leftsum+=nums[i];
            leftBordersum=leftsum>leftBordersum?leftsum:leftBordersum;
        }
        
        int rightBordersum=nums[center+1];
        int rightsum=nums[center+1];
        for(int i=center+2;i<=right;i++){
            rightsum+=nums[i];
            rightBordersum=rightsum>rightBordersum?rightsum:rightBordersum;
        }
        int BorderSum = leftBordersum + rightBordersum;
        int max=leftmax>rightmax ? leftmax:rightmax;
        return max>BorderSum ? max:BorderSum;
    }
}

300. Longest Increasing Subsequence

Given an unsorted array of integers, find the length of longest increasing subsequence.

Example:

Input: [10,9,2,5,3,7,101,18]
Output: 4 
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 

Note:

  • There may be more than one LIS combination, it is only necessary for you to return the length.
  • Your algorithm should run in O(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

class Solution {
public://动态规划。时间复杂度为O(n^2)。
    int lengthOfLIS(vector<int>& nums) {
        int n=nums.size();
        if(n <= 1) return n;
        vector<int> dp(n, 1);
        for(int i=1;i<n;i++)
        {//dp[i]表示LIS的长度。nums[i]作为LIS的最后一个元素。
            for(int j=0;j<i;j++)
            {
                if(nums[i] > nums[j])
                {//满足递增
                    dp[i]=max(dp[i], dp[j]+1);//利用状态转移方程
                }
            }
        }
        int res=0;
        for(int i=0;i<n;i++)
        {//求得最大的dp[i]
            res = max(res, dp[i]);
        }
        return res;
    }
};
原文地址:https://www.cnblogs.com/wangcl-8645/p/11313151.html