子序列的最大和
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;
}
};