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