Conceptos básicos de la estructura de datos día 9

Tema: 187. Secuencias repetidas de ADN.

Solución 1: tabla hash

class Solution {
    
    
public:
    vector<string> findRepeatedDnaSequences(string s) {
    
    
        vector<string> ans;
        unordered_map<string, int> mp;
        int n=s.size(), L=10;
        for(int i=0; i<=n-L; ++i){
    
    	//从开头遍历到最后一个长度为10的子串开头
            string temp = s.substr(i,L);
            if(++mp[temp]==2){
    
    	//当数量==2时即可加入答案序列
                ans.push_back(temp);
            }
        }
        return ans;
    }
};

Solución 2: tabla hash + ventana deslizante + operación de bits

Es tan largo que no quiero leerlo.

Tema: 5. La subcadena palíndromo más larga

Solución 1: solución violenta

Recorra cada subcadena y, cuando sea una subcadena palíndromo con la longitud más grande, almacene la posición y la longitud iniciales.
Complejidad del tiempo O (n ^ 3), complejidad del espacio O (1)

class Solution {
    
    
public:
    bool isPalindrome(string s, int left, int right){
    
    	//判断s字符串中left到right位置的子串是否为回文串
        while(left<right){
    
    
            if(s[left] != s[right]) return false;
            ++left; --right;
        }
        return true;
    }

    string longestPalindrome(string s) {
    
    
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大长度可以是一个字母
        int begin = 0;	//初始位置

        for(int i=0; i<n-1; ++i){
    
    	//遍历头,注意遍历到n-1
            for(int j=i+1; j<n; ++j){
    
    	//遍历从i开始的子串的尾,
                if(j-i+1>maxLen && isPalindrome(s, i, j)){
    
    	//当子串长度大于当前最大长度,且子串为回文串
                    maxLen = j-i+1;	//更新最大长度
                    begin = i;	//更新起始位置
                }
            }
        }

        return s.substr(begin, maxLen);	//返回s的最大长度回文子串
    }
};

Solución 2: programación dinámica

Es equivalente a intercambiar espacio por tiempo basado en la solución de fuerza bruta. La complejidad del tiempo es O(n^2) y la complejidad del espacio es O(n).Definición de estado (subproblema de definición): si una cadena es
un palíndromo cadena después de eliminar los dos caracteres Si la cadena es una cadena palíndromo, por lo que el subproblema se define como: dp[i][j]Expresado s[i,...,j]como una ecuación de transición de estado de subcadena palíndromo
(que describe la conexión entre subproblemas) : dp[i][j] = (s[i]==s[j]) && (dp[i+1][j-1]=true)
Inicialización : La condición límite es que cuando la longitud de la subcadena es 1, obviamente es una cadena palíndromo. Subcadena de texto, por ejemplo, icuando jlos caracteres en las posiciones i y j de una subcadena son iguales, se juzga si la longitud de la subcadena después de eliminar los caracteres de posición iy jes un palíndromo. subcadena, y se juzga unánimemente que la longitud de la subcadena después de eliminar ilos caracteres de posición y -> Salida : indica si la subcadena es una subcadena palíndromo, determine si es quemayorjj-1-(i+1)+1<2j-i<3
dp[i][j]ijj-i+1maxLenmaxLenbegin=i


Insertar descripción de la imagen aquí

class Solution {
    
    
public:
    string longestPalindrome(string s) {
    
    
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        vector<vector<int>> dp(n, vector<int>(n));	//dp定义,true是非0数,false是0
        for(int i=0; i<n; ++i){
    
    	//初始定义,每个字符单独都是回文子串,对角线为true
            dp[i][i] = true;
        }
        for(int j=1; j<n; ++j){
    
    	//从左上角开始遍历,注意从1开始,先遍历列
            for(int i=0; i<j; ++i){
    
    	//后遍历行,到对角线(j)为止
                if(s[i]!=s[j]) dp[i][j]=false;	//如果i和j位置的字符不相同,则直接false
                else{
    
    	//i和j位置字符相同
                    if(j-i<3){
    
      //边界:j-1-(i+1)+1<2 -> j-i<3
                        dp[i][j] = true;
                    }else{
    
    	//继续判断i+1到j-1的子串
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
                if(dp[i][j]==true && j-i+1>maxLen){
    
    	//检查i到j子串长度是否大于maxLen
                    maxLen = j-i+1;	//更新最大回文子串长度
                    begin = i;	//更新最大回文子串初始位置
                }
            }
        }

        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

Solución 3: método de expansión central

Complejidad del tiempo: O (n ^ 2), complejidad del espacio: O (1).
Enumere el número de posiciones centrales 2 (n-1). Cada centro se extiende a ambos lados para ver si es una subcadena palíndromo, un número par. subcadena palíndromo y subcadenas palíndromo impares

class Solution {
    
    
public:
    int ExpandfromCentre(string s, int i, int j){
    
    	//从中心开始扩展,检查扩展子串是否是回文子串
        int n = s.size();
        int left = i, right = j;
        while(left>=0 && right<n){
    
    
            if(s[left]==s[right]){
    
    
                --left;
                ++right;
            }else{
    
    
                break;
            }
        }   //不符合i和j位置的字符相同时退出循环,因此返回的回文子串的长度为j-1-(i+1)+1=j-i-1,这里是left和right!!!
        return right-left-1;
    }

    string longestPalindrome(string s) {
    
    
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        for(int i=0; i<n-1; ++i){
    
    	//枚举中心位置
            int oddLen = ExpandfromCentre(s, i, i);	//最大奇数回文子串长度
            int evenLen = ExpandfromCentre(s, i, i+1);	//最大偶数回文子串长度
            if(max(oddLen, evenLen) > maxLen){
    
    	//更新maxLen和begin
                maxLen = max(oddLen, evenLen);
                begin = i-(maxLen-1)/2;	//注意这里是推导出来的
            }
        }
        
        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

Es un poco problemático presionar el inicio desde i y maxLen, puedes elegir otra forma de escribir:

class Solution {
    
    
public:
    pair<int, int> ExpandfromCentre(string s, int i, int j){
    
    	//注意函数类型是pair
        int n = s.size();
        int left = i, right = j;
        while(left>=0 && right<n){
    
    
            if(s[left]==s[right]){
    
    
                --left;
                ++right;
            }else{
    
    
                break;
            }
        }   //不符合i和j位置的字符相同时退出循环,因此返回的回文子串的长度为j-1-(i+1)+1=j-i-1,这里是left和right!!!
        return {
    
    left+1, right-1};	//注意返回值和{}
    }

    string longestPalindrome(string s) {
    
    
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        for(int i=0; i<n-1; ++i){
    
    
            auto [odd_l, odd_r] = ExpandfromCentre(s, i, i);	//注意加[]
            auto [even_l, even_r] = ExpandfromCentre(s, i, i+1);
            if(odd_r-odd_l+1 > maxLen){
    
    
                maxLen = odd_r-odd_l+1;
                begin = odd_l;
            }
            if(even_r-even_l+1 > maxLen){
    
    
                maxLen = even_r-even_l+1;
                begin = even_l;
            }
        }
        
        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

Supongo que te gusta

Origin blog.csdn.net/qq_43606119/article/details/130389593
Recomendado
Clasificación