Mi informacion de contacto
Correo[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Tabla de contenido
Tema 1: El prefijo común más largo
Pregunta 2: la subcadena palíndromo más larga
Pregunta 4: Multiplicar cadenas
Escriba una función para encontrar el prefijo común más largo en una matriz de cadenas
Si no existe un prefijo común, devuelve una cadena vacía""
Ejemplo 1:
输入:strs = ["flower","flow","flight"] 输出:"fl"
Ejemplo 2:
输入:strs = ["dog","racecar","car"] 输出:"" 解释:输入不存在公共前缀。
pista:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i]
Consta únicamente de letras inglesas minúsculas.Solución 1: comparación por pares
La primera solución es la estrategia de comparación por pares. Primero compare las dos primeras cadenas. Después de la comparación, compare el prefijo común de las dos primeras cadenas con la tercera cadena para obtener el prefijo común de las tres primeras cadenas, y así sucesivamente.
El código se muestra a continuación:
- class Solution
- {
- public:
- string findCommon(string& s1, string& s2)
- {
- int i = 0;
- //i有可能会出现越界的情况,所以i小于s1s2长度时再循环判断
- while(i < min(s1.size(), s2.size()) && s1[i] == s2[i])
- i++;
- return s1.substr(0, i);
- }
-
- string longestCommonPrefix(vector<string>& strs)
- {
- int n = strs.size();
- //same字符串就是存储最长公共前缀的字符串
- string same = strs[0];
- for(int i = 1; i < n; i++)
- same = findCommon(same, strs[i]);
- return same;
- }
- };
Solución 2: comparación unificada
La comparación unificada significa comparar la misma posición de todas las cadenas a la vez para determinar si las posiciones son las mismas hasta que aparecen caracteres diferentes.
Habrá una situación fuera de límites aquí. Si hay una situación fuera de límites, significa que una determinada cadena ha finalizado y luego se puede finalizar la comparación.
El código se muestra a continuación:
- class Solution
- {
- public:
- string longestCommonPrefix(vector<string>& strs)
- {
- int i = 0;
- //以第一个字符串为基准,与其他所有字符串做比较
- for(i = 0; i < strs[0].size(); i++)
- {
- //ch表示第一个字符串当前循环到的字符
- char ch = strs[0][i];
- //循环strs中其余的字符串,其余字符串的i位置字符与ch做比较
- for(int j = 1; j < strs.size(); j++)
- {
- //如果i大于当前字符串的长度,说明当前字符串已经没有元素了
- if(i > strs[j].size() || strs[j][i] != ch)
- return strs[0].substr(0, i);
- }
- }
- return strs[0];
- }
- };
darte una cuerdas
,aparecers
La subcadena palíndromo más larga en
Ejemplo 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
Ejemplo 2:
输入:s = "cbbd" 输出:"bb"
El algoritmo de enumeración de fuerza bruta ordinario establece dos punteros, uno i y otro j, fija i y mueve j hacia atrás. Cada vez que se mueve j, es necesario determinar si la cadena entre i y j es una subcadena palíndromo. j se mueve. Y al juzgar si hay una subcadena palíndromo entre i y j, la complejidad del tiempo aquí es O (N ^ 2), y debido a que hay una capa de i anidada afuera, que se usa para atravesar toda la cadena, la todo el tiempo de enumeración violenta La complejidad es muy alta y alcanza O (N ^ 3). Veamos el algoritmo de expansión central optimizado:
Solución: algoritmo de expansión central
El algoritmo de expansión central es:
①Fijar un punto central
②Comience desde el punto central y expanda hacia ambos lados (se deben considerar las longitudes pares e impares)
Es decir, se fija un punto central i cada vez, y cada vez se expande hacia la izquierda y hacia la derecha de i para determinar si es una cadena palíndromo. La complejidad temporal de este algoritmo que atraviesa i es O (N). y la dirección anidada está a la izquierda y a la derecha de i. Por extensión, la complejidad del tiempo también es O (N), por lo que al final es O (N ^ 2), que está mucho más optimizada que la solución violenta mencionada anteriormente. .
Lo que hay que tener en cuenta es que se deben tener en cuenta los números pares e impares del segundo punto del algoritmo de expansión central, porque los números impares mueven los punteros izquierdo y derecho desde la posición i hacia la izquierda y la derecha, mientras que los números pares requieren. izquierda para estar en la posición i y derecha para estar en la posición i + 1, y luego moverse hacia la izquierda y hacia la derecha
Cabe señalar que la longitud en el código es derecha-izquierda-1, porque si la izquierda y la derecha actuales apuntan al mismo elemento, debe cambiar izquierda--, derecha++, si no son iguales, salga del ciclo. , por lo que hay más cadenas izquierda y derecha que palíndromos. Se ha movido una posición, por lo que la longitud se calcula de derecha a izquierda - 1. Consulte la figura a continuación para obtener más detalles:
Como se muestra en la figura anterior, la izquierda y la derecha apuntan al punto actual para salir del bucle, por lo que la longitud de la subcadena palíndromo aa es:
derecha - izquierda - 1 = 3 - 0 - 1 = 2
El código se muestra a continuación:
- class Solution
- {
- public:
- string longestPalindrome(string s)
- {
- if(s.size() == 1) return s;
- int n = s.size(), begin = 0, size = 0;
- for(int i = 0; i < n; i++)
- {
- //先做奇数长度的扩展
- int left = i, right = i;
- //left和right符合条件,且指向元素相等再进入循环
- while(left >= 0 && right < n && s[left] == s[right])
- {
- --left;
- ++right;
- }
- //如果长度更大,更新begin与size
- if((right - left - 1) > size)
- {
- size = right - left - 1;
- begin = left + 1;
- }
- //再做偶数长度的扩展
- left = i, right = i + 1;
- //left和right符合条件,且指向元素相等再进入循环
- while(left >= 0 && right < n && s[left] == s[right])
- {
- --left;
- ++right;
- }
- //如果长度更大,更新begin与size
- if((right - left - 1) > size)
- {
- size = right - left - 1;
- begin = left + 1;
- }
- }
- return s.substr(begin, size);
- }
- };
Darte dos cadenas binariasa
yb
, devolviendo su suma como una cadena binaria.
Ejemplo 1:
输入:a = "11", b = "1" 输出:"100"
Ejemplo 2:
输入:a = "1010", b = "1011" 输出:"10101"
Esta pregunta trata sobre el cálculo de la suma de alta precisión, la realización de una operación de simulación y la simulación del proceso de cálculo vertical.
Debe configurar dos punteros, cur1 y cur2, para que apunten a dos cadenas respectivamente, y luego configurar una variable t para representar el acarreo.
El código se muestra a continuación:
- class Solution
- {
- public:
- string addBinary(string a, string b)
- {
- //t表示相加后的进位
- int t = 0;
- string ret;
- int cur1 = a.size()-1, cur2 = b.size()-1;
- //cur1或cur2 >= 0表示字符串没遍历完,t>0表示还剩一个进位
- while(cur1 >= 0 || cur2 >= 0 || t)
- {
- if(cur1 >= 0) t += a[cur1--] - '0';
- if(cur2 >= 0) t += b[cur2--] - '0';
- ret += to_string(t % 2);
- t /= 2;
- }
- //从后向前加的,刚好反过来了,需要逆置
- reverse(ret.begin(), ret.end());
- return ret;
- }
- };
Dados dos números enteros no negativos representados como cadenasnum1
ynum2
,devolvernum1
ynum2
El producto de , su producto también se expresa en forma de cadena.
Aviso:No puede utilizar ninguna de las bibliotecas integradas de BigInteger ni convertir directamente la entrada a un número entero.
Ejemplo 1:
输入: num1 = "2", num2 = "3" 输出: "6"
Ejemplo 2:
输入: num1 = "123", num2 = "456" 输出: "56088"
Solución 1: Simular operaciones verticales
En matemáticas, es la forma vertical de la columna de multiplicación. Este es el método más fácil de imaginar.
Como sigue:
Podemos entenderlo como, cada dígito del siguiente 456 se multiplica por el 123 anterior y luego se suma, hay tres detalles:
①La multiplicación de orden superior debe completarse con 0, porque un bit falla al sumar 738 y 615, lo que puede entenderse como 738 + 6150
②Proceso líder 0, puede ocurrir una situación de 123 × 0, en cuyo caso la respuesta es 000 y debe procesarse.
③Preste atención al orden de los resultados del cálculo., porque el cálculo se realiza en orden inverso y la multiplicación se calcula a partir del último dígito.
Pero este método no es fácil de escribir código. Necesitamos utilizar este método para optimizarlo.
Solución dos: optimizar la solución uno
Multiplica y suma sin acarreo, y el acarreo se procesa en el último paso:
Es decir, no importa cuánto se multiplique, no habrá acarreo y el acarreo se realizará después de la suma final.
De manera similar, al comenzar el cálculo, primero invierta el orden. Dado que la multiplicación puede tener dos dígitos, no se puede usar la representación de cadena. En su lugar, se puede usar una matriz para almacenar.
Como el orden está invertido, el subíndice correspondiente a 123 es 2,1,0 y el subíndice correspondiente a 456 también es 2,1,0
Hay una regla muy útil: los números subíndices de i y j se multiplican y el resultado se coloca en la posición i + j de la matriz.
① Defina una matriz tmp con una longitud de m + n - 1 (m y n corresponden a las longitudes de dos números multiplicados)
Los subíndices de los dos números que se multiplican son i y j respectivamente, y el resultado calculado se coloca en la posición i + j de la matriz.
②Después de la adición final, es necesario procesar el acarreo.
③Procesamiento inicial 0
El código se muestra a continuación:
- class Solution
- {
- public:
- string multiply(string num1, string num2)
- {
- //先逆序两个字符串
- reverse(num1.begin(), num1.end());
- reverse(num2.begin(), num2.end());
- //定义一个数组tmp
- int m = num1.size(), n = num2.size();
- vector<int> tmp(m + n - 1);
- //无进位相乘然后相加
- for(int i = 0; i < m; i++)
- for(int j = 0; j < n; j++)
- tmp[i + j] += (num1[i] - '0') * (num2[j] - '0');
- //处理进位
- string ret;
- int t = 0, cur = 0;
- while(cur < m + n - 1 || t != 0)
- {
- if(cur < m + n - 1) t += tmp[cur++];
- ret += to_string(t % 10);
- t /= 10;
- }
- if(t) ret += to_string(t);
- //处理前置0
- while(ret.back() == '0' && ret.size() > 1) ret.pop_back();
- reverse(ret.begin(), ret.end());
-
- return ret;
- }
- };
Esto finaliza las preguntas relacionadas con cadenas.