1 最大子序和
题目
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
链接:https://leetcode-cn.com/problems/maximum-subarray/
思路
状态 :d p [ i ] dp[i] d p [ i ] 代表以n u m s [ i ] nums[i] n u m s [ i ] 结尾的最大和
状态转移方程 :d p [ i ] = m a x ( d p [ i − 1 ] + n u m s [ i ] , n u m s [ i ] ) dp[i] = max(dp[i-1]+nums[i], nums[i]) d p [ i ] = m a x ( d p [ i − 1 ] + n u m s [ i ] , n u m s [ i ] )
答案 :m a x ( d p [ 0 . . . n − 1 ] ) max(dp[0...n-1]) m a x ( d p [ 0 . . . n − 1 ] )
时间复杂度 :循环执行 n 次,每次花费常数的时间代价,故渐进时间复杂度为 O ( n ) O(n) O ( n ) 。
空间复杂度 :O ( n ) O(n) O ( n ) ,可用滚动数组优化到O ( 1 ) O(1) O ( 1 ) 。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution {public : int maxSubArray (vector <int >& nums) { int n = nums.size (); int pre = nums[0 ]; int ans = nums[0 ]; for (int i = 1 ; i < n; i++) { pre = max (nums[i], pre + nums[i]); ans = max (ans, pre); } return ans; } };
2 最长上升子序列
题目
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
链接:https://leetcode-cn.com/problems/longest-increasing-subsequence/
思路
状态 :d p [ i ] dp[i] d p [ i ] 代表以n u m s [ i ] nums[i] n u m s [ i ] 结尾的最长严格递增子序列的长度
状态转移方程 :d p [ i ] = m a x ( d p [ j ] + 1 , d p [ i ] ) dp[i] = max(dp[j]+1,dp[i]) d p [ i ] = m a x ( d p [ j ] + 1 , d p [ i ] ) ,j < i j<i j < i 且n u m s [ i ] > n u m s [ j ] nums[i]>nums[j] n u m s [ i ] > n u m s [ j ]
答案 :max(dp[0…n-1])
时间复杂度 : O ( n 2 ) O(n^2) O ( n 2 )
空间复杂度 : O ( n ) O(n) O ( n )
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : int lengthOfLIS (vector <int >& nums) { int n = nums.size (); int dp[n]; dp[0 ] = 1 ; for (int i = 1 ; i < n; i++) { dp[i] = 1 ; for (int j = 0 ; j < i; j++) { if (nums[i] > nums[j]) { dp[i] = max (dp[i], dp[j] + 1 ); } } } return *max_element(dp, dp + n); } };
3
Life is painting a picture, not doing a sum.