Tema: 290. Patrones de palabras.
Solución: doble mapeo
Esto es para encontrar un mapeo bidireccional. Si se cumple el doble mapeo de str2ch y ch2str, devolverá verdadero, de lo contrario devolverá falso.
La complejidad del tiempo es O(m+n), n es la longitud del patrón, m es la longitud de s, y el tiempo amortizado de insertar y consultar la tabla hash es complejo, el grado es O (m + n), y cada carácter se puede atravesar como máximo una vez.
La complejidad del espacio es O (m+n), n es la longitud del patrón, m es la longitud de s y, en el peor de los casos, se almacenan todos los caracteres del patrón y 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
}
};
Tema: 763. Dividir intervalos de letras
El objetivo principal es encontrar los punteros de cabeza y cola de la subcadena. Dado que la misma letra solo puede aparecer en el mismo segmento, obviamente la primera posición del subíndice y la última posición del subíndice de la misma letra deben aparecer en el mismo segmento . Por lo tanto, es necesario recorrer la cadena y obtener la posición del subíndice de la última aparición de cada letra. Actualice el final del fragmento actual y luego intercepte la longitud de la subcadena.
Solución: codicioso
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;
}
};