判斷子序列
題目連結:392. 判斷子序列 - 力扣(LeetCode)
思路:從子串s開始遍歷,查詢t中是否存在,因為全程不需要回溯,因此兩個for迴圈就解決了。只是要注意return的時機。(只要不想寫的很簡潔,邏輯挺簡單的其實)
class Solution {
public:
bool isSubsequence(string s, string t) {
if(s.size()>t.size())return false;
int j=0;
for(int i=0;i<s.size();i++){
for(;j<t.size();j++){
if(s[i]==t[j]){
j++;
if(i==s.size()-1&&j==t.size())return true;
break;
}
}
if(j==t.size())return false;
}
return true;
}
};
簡潔寫法來了,不愧是k神。
class Solution {
public:
bool isSubsequence(string s, string t) {
if (s.size() == 0) return true;
for (int i = 0, j = 0; j < t.size(); j++) {
if (s[i] == t[j]) {
// 若已經遍歷完 s ,則提前返回 true
if (++i == s.size())
return true;
}
}
return false;
}
};
作者:Krahets
連結:https://leetcode.cn/problems/is-subsequence/solutions/1658262/by-jyd-zeph/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
不同的子序列
題目連結:115. 不同的子序列 - 力扣(LeetCode)
思路:第一思路是想到和過去寫的回溯很像,因此想用回溯寫,但是……
class Solution {
public:
int result;
void backtracking(string s,string t,int sindex,int tindex){
if(tindex==t.size()){
result++;
}
for(int i=sindex;i<s.size();i++){
if(s[i]==t[tindex]){
backtracking(s,t,i+1,tindex+1);
}
}
}
int numDistinct(string s, string t) {
if(s.size()<t.size())return 0;
int mod = 1000000000 + 7;
backtracking(s,t,0,0);
return result%mod;
}
};
只能學習官網的dp方法了。dp[i][j]:以i-1為結尾的s子序列中出現以j-1為結尾的t的個數為dp[i][j]。
dp[i][0] 表示:以i-1為結尾的s可以隨便刪除元素,出現空字串的個數。
那麼dp[i][0]一定都是1,因為也就是把以i-1為結尾的s,刪除所有元素,出現空字串的個數就是1。
再來看dp[0][j],dp[0][j]:空字串s可以隨便刪除元素,出現以j-1為結尾的字串t的個數。
那麼dp[0][j]一定都是0,s如論如何也變成不了t。
最後就要看一個特殊位置了,即:dp[0][0] 應該是多少。
dp[0][0]應該是1,空字串s,可以刪除0個元素,變成空字串t。
class Solution {
public:
int numDistinct(string s, string t) {
vector<vector<uint64_t>> dp(s.size() + 1,
vector<uint64_t>(t.size() + 1));
for (int i = 0; i < s.size(); i++)
dp[i][0] = 1;
for (int j = 1; j < t.size(); j++)
dp[0][j] = 0;
for (int i = 1; i <= s.size(); i++) {
for (int j = 1; j <= t.size(); j++) {
if (s[i - 1] == t[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[s.size()][t.size()];
}
};