300. 最長遞增子序列
題目連結:https://leetcode.cn/problems/longest-increasing-subsequence/
文章講解:https://programmercarl.com/0300.最長上升子序列.html
題目難度:中等
影片講解:https://www.bilibili.com/video/BV1ng411J7xP
題目狀態:有思路,但是自己能寫出來還是太勉強,有些細節想不到
思路:
維護一個動規陣列dp[i],表示在遍歷到陣列中的第i個元素的時候,此時能找到的最長遞增子序列的長度。
其更新的程式碼如下:if(num[i] > num[j]) dp[i] = max(dp[i], dp[j] + 1);
所以需要有兩次遍歷,i是整個陣列的遍歷,j是在當前元素前面的元素,這樣就能確保dp[i]是當前最大的遞增子序列的個數。
程式碼:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size() <= 1) return nums.size();
vector<int> dp(nums.size(), 1);
int ans = 0;
for(int i = 1; i < nums.size(); ++i) {
for(int j = 0; j < i; ++j) {
if(nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
}
ans = ans < dp[i] ? dp[i] : ans;
}
return ans;
}
};
674. 最長連續遞增序列
題目連結:https://leetcode.cn/problems/longest-continuous-increasing-subsequence/
文章講解:https://programmercarl.com/0674.最長連續遞增序列.html
題目難度:簡單
影片講解:https://www.bilibili.com/video/BV1bD4y1778v
題目狀態:這題比較簡單,久違的獨立透過
思路:
相較於上題,這題很簡單,dp陣列的更新只要依靠前一個元素就可以,若當前元素大於前一個元素,就將前一個元素的dp陣列加1。
程式碼:
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
if(nums.size() <= 1) return nums.size();
vector<int> dp(nums.size(), 1);
int ans = 0;
for(int i = 1; i < nums.size(); ++i) {
if(nums[i] > nums[i - 1]) dp[i] = dp[i - 1] + 1;
ans = ans < dp[i] ? dp[i] : ans;
}
return ans;
}
};
貪心思路和程式碼:
維護一個變數count
用來存放當前的連續遞增序列的長度,如果遇到nums[i] > nums[i - 1]
的情況,count就++,否則count就為1,記錄count的最大值就可以了。
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
if(nums.size() <= 1) return nums.size();
int ans = 0;
int count = 1;
for(int i = 1; i < nums.size(); ++i) {
if(nums[i] > nums[i - 1]) count++;
else count = 1;
ans = ans < count ? count : ans;
}
return ans;
}
};
718. 最長重複子陣列
題目連結:https://leetcode.cn/problems/maximum-length-of-repeated-subarray/
文章講解:https://programmercarl.com/0718.最長重複子陣列.html
題目難度:中等
影片講解:https://www.bilibili.com/video/BV178411H7hV
題目狀態:看題解
思路
維護一個二維動規陣列d[i][j],表示在陣列1中元素為i-1和陣列2中元素為j-1時的最長重複子陣列的大小。
若要更新這個動規陣列,我們要進行巢狀迴圈,第一個迴圈是陣列1,第二個迴圈是陣列2,其更新的條件是nums1[i - 1] = nums2[j - 1]
,至於為什麼是i-1和j-1,因為這樣我們可以從1開始比較,避免處理i或j為0時的特殊情況。
程式碼
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int len1 = nums1.size();
int len2 = nums2.size();
int ans = 0;
vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1, 0));
for(int i = 1; i <= len1; ++i) {
for(int j = 1; j <= len2; ++j) {
if(nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
ans = ans < dp[i][j] ? dp[i][j] : ans;
}
}
return ans;
}
};