トピック: 290. 単語パターン
解決策: 二重マッピング
それは双方向マッピングを見つけることです. str2ch と ch2str の二重マッピングが満たされる場合は true を返します, それ以外の場合は false を返します.
時間計算量は O(m+n), n はパターンの長さ, m は長さですの s であり、ハッシュ テーブルの挿入とクエリの償却時間は複雑です。次数は O(m+n) で、各文字を最大 1 回走査できます。
空間複雑度は O(m+n) で、n はパターンの長さ、m は s の長さで、最悪の場合、パターン内のすべての文字と s が格納されます。
class Solution {
public:
bool wordPattern(string pattern, string s) {
unordered_map<string, char> str2ch; //str2ch的映射
unordered_map<char, string> ch2str; //ch2str的映射
int m = s.size(); //s的长度
int i=0; //遍历指针
for(char ch:pattern){
//根据pattern长度进行遍历
if(i>=m) return false; //pattern仍然存在字符可以遍历,而遍历指针已经超过m,即pattern长度大于s长度,返回false
int j=i; //子串遍历指针
while(j<m&&s[j]!=' ') ++j; //选择子串
string temp = s.substr(i,j-i); //截取子串,注意substr的用法,substr(i,j),从第i个位置开始截取j项字符
if(str2ch.count(temp)&&str2ch[temp]!=ch){
//判断str2ch映射
return false;
}
if(ch2str.count(ch)&&ch2str[ch]!=temp){
//判断ch2str映射
return false;
}
str2ch[temp]=ch; //更新映射
ch2str[ch]=temp;
i=j+1; //更新遍历指针,这里j指在空格处,所以i要+1,指向下一个子串的起始位置
}
// return true;
return i>=m; //此时已经出了pattern的循环,意味着pattern字符遍历结束,此时如果i小于m,意味着s没有遍历结束,即pattern长度小于s长度,返回false,否则两者遍历结束返回true
}
};
トピック: 763. 文字間隔を分割する
主な目的は、部分文字列の先頭と末尾のポインタを見つけることです。同じ文字は同じセグメント内にのみ出現できるため、当然のことながら、同じ文字の最初の添え字位置と最後の添え字位置は同じセグメント内に出現する必要があります。したがって、文字列を走査して、各文字が最後に出現する添え字の位置を取得する必要があります。現在のフラグメントの末尾を更新し、部分文字列の長さをインターセプトします。
解決策: 貪欲な
class Solution {
public:
vector<int> partitionLabels(string s) {
int last[26]; //存储每个字符最后一次出现的下标位置
int n = s.size();
for(int i=0; i<n; ++i){
last[s[i]- 'a'] = i;
}
int start = 0, end = 0; //每个子串的头尾指针
vector<int> ans; //存储子串长度
for(int i=0; i<n; ++i){
//遍历每个字符
end = max(end, last[s[i]-'a']); //更新end,取当前end和当前字符最后一次出现位置的最大值
if(i==end){
//如果i已经遍历到end,说明子串确定
ans.push_back(end-start+1); //存储子串长度
start = end + 1; //更新下一个子串的起始位置
}
}
return ans;
}
};