- Grabado el 17 de mayo de 2019
Directorio de artículos
-
-
-
- [4. Encuentre la mediana de dos matrices ordenadas] (https://leetcode.com/problems/median-of-two-sorted-arrays/)
- [5. La subcadena palíndroma más larga] (https://leetcode.com/problems/longest-palindromic-substring/)
- [10. Coincidencia de expresiones regulares] (https://leetcode.com/problems/regular-expression-matching/)
-
-
-
4. Encuentra la mediana de dos arreglos ordenados
① Descripción del título
- Dados dos arreglos ordenados nums1 y nums2 de tamaño my n.
- Encuentre la mediana de estas dos matrices ordenadas y la complejidad de tiempo del algoritmo requerido es
O(log(m + n))
. - Puede asumir que nums1 y nums2 no estarán vacíos al mismo tiempo.
- Ejemplo 1:
nums1 = [1, 3] nums2 = [2]
entonces la mediana es 2.0
- Ejemplo 2:
nums1 = [1, 2] nums2 = [3, 4]
entonces la mediana es (2 + 3) / 2 = 2.5
② Solución violenta
- Primero considere el caso donde la longitud de nums1 o nums2 es 0, y devuelva directamente la mediana de otra matriz.
- Atraviese nums1 y nums2, almacene los datos en otra matriz, use
Arrays.sort()
para ordenar la nueva matriz y luego devuelva la mediana. - Complejidad de tiempo: atraviesa toda la matriz
O(lm + n)
. - Complejidad espacial: abre una matriz, la matriz después de guardar dos combinados
O(m + n)
. - El código es el siguiente (¡pasó mágicamente!):
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length, n = nums2.length;
if (m == 0) {
if (n % 2 == 0) {
return (nums2[n / 2] + nums2[n / 2 - 1]) / 2.0;
} else {
return (double) nums2[(n - 1) / 2];
}
}
if (n == 0) {
if (m % 2 == 0) {
return (nums1[m / 2] + nums1[m / 2 - 1]) / 2.0;
} else {
return (double) nums1[(m - 1) / 2];
}
}
int[] temp = new int[m + n];
int i = 0;
for (; i < m; i++) {
temp[i] = nums1[i];
}
for (int j = 0; j < n; j++) {
temp[i + j] = nums2[j];
}
Arrays.sort(temp);
int len = temp.length;
if (len % 2 == 0) {
return (temp[len / 2] + temp[len / 2 - 1]) / 2.0;
} else {
return (double) temp[(len - 1) / 2];
}
}
5. La subcadena palíndromo más larga
① Descripción del título
- Dada una cadena s, encuentre la subcadena palíndromo más larga en s. Puede suponer que la longitud máxima de s es 1000.
- Ejemplo 1:
Entrada: "babad"
Salida: "bab"
Nota: "aba" también es una respuesta válida.
- Ejemplo 2:
Entrada: "cbbd"
Salida: "bb"
② Solución violenta (límite de tiempo excedido)
- Primero, juzgue si s está vacío o si la longitud es 1 y devuelva s directamente.
helper()
Método de escritura , utilizado para determinar si sub es una subcadena palíndromo.- Subcadena palíndromo de búsqueda por fuerza bruta, nota: cuando el
helper()
método devuelve el resultadotrue
, es necesario comparar la longitud de la subcadena actual y el resultado intermedio. - Dado que la longitud inicial del juicio es 2 durante la búsqueda crítica, si está al final
max=0
, significa que no se encuentra la subcadena palíndromo con una longitud mayor o igual a 2, y el primer carácter de s se devuelve directamente.
- el código se muestra a continuación:
public String longestPalindrome(String s) {
int len = s.length();
if (len == 0 || len == 1) {
return s;
}
String result = new String("");
int max = 0;
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
String temp = s.substring(i, j + 1);
if (helper(temp) && max < temp.length()) {
result = temp;
max = temp.length();
}
}
}
if (max == 0) {
return s.substring(0, 1);
}
return result;
}
public boolean helper(String s) {
int start = 0, end = s.length() - 1;
while (start <= end) {
if (s.charAt(start) == s.charAt(end)) {
start++;
end--;
} else {
return false;
}
}
return true;
}
③ Planificación dinámica
- La programación dinámica generalmente utiliza almacenamiento de matriz bidimensional para intercambiar espacio por tiempo.
- Se observa que hay que saber
P(i, j)
antes de saberP(i+1, j-1)
, por lo外层循环i
que debería倒序遍历
, desden-1, ...., 0
; el内层循环j
valor inicial debe ser i (debido a la2, 0
situación imposible , solo se puede encontrar la cuerda de adelante hacia atrás), yj
se debe atravesar secuencialmente, por un lado, para asegurar que el niño sea encontrado de adelante hacia atrás. Las cadenas, por otro lado, se garantizaP(i+1, j-1)
que se resolverán primero.
public String longestPalindrome(String s) {
int len = s.length();
int max = 0;
String result = new String("");
boolean[][] d = new boolean[len][len];
for (int i = len - 1; i >= 0; i--) {
for (int j = i; j < len; j++) {
if (i == j) {
d[i][j] = true;
} else if (i + 1 == j) {
d[i][j] = (s.charAt(i) == s.charAt(j)) ? true : false;
} else {
d[i][j] = (d[i + 1][j - 1] && s.charAt(i) == s.charAt(j)) ? true : false;
}
if (d[i][j] && (j - i + 1) > max) {
result = s.substring(i, j + 1);
max = j - i + 1;
}
}
}
return result;
}
10. Coincidencia de expresiones regulares
① Descripción del título
- Dada una (s) cadena (s) y un patrón de caracteres§. La implementación admite la coincidencia de expresiones regulares de '.' Y '*'.
'.'
Coincide con cualquier carácter individual.'*'
Coincidir con cero o más elementos precedentes.- La coincidencia debe cubrir toda la cuerda (s), no parte de la cuerda.
- Descripción:
s puede estar vacío y solo contener letras minúsculas de az.
p puede estar vacío y solo contener letras minúsculas de az, y los caracteres. y *.
- Ejemplo 1:
Entrada:
s = "aa"
p = "a"
Salida: falso
Explicación: "a" no puede coincidir con la cadena completa de "aa".
- Ejemplo 2:
Entrada:
s = "aa"
p = "a *"
Salida: verdadera
Explicación: '*' significa que puede coincidir con cero o más elementos anteriores, es decir, puede coincidir con 'a'. Por lo tanto, repitiendo 'a' una vez, la cadena se convierte en "aa".
- Ejemplo 3:
Entrada:
s = "ab"
p = ". "
Salida: verdadera
Explicación: ". " Significa que puede coincidir con cero o más ('*') caracteres arbitrarios ('.').
- Ejemplo 4:
Entrada:
s = "aab"
p = "c a b"
Salida: verdadera
Explicación: 'c' no se puede repetir, 'a' se puede repetir una vez. Entonces puede coincidir con la cadena "aab".
- Ejemplo 5:
Entrada:
s = "mississippi"
p = "mis es p *."
Salida: falso
② Utilice java.String API
public boolean isMatch(String s, String p) {
if (s==null){
if (p==null){
return true;
}else{
return false;
}
}
if (p==null){
return false;
}
return s.matches(p);
}
③ Programación dinámica (¡no entiendo!)
- Blog de referencia: Pregunta 10 coincidencia de expresiones regulares (programación dinámica)
public boolean isMatch(String s, String p) {
int m = s.length(), n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[0][0] = true;//考虑s和p均为空的情况
// 考虑s为空,p不为空的情况,遇到'*',p的下标-2
for (int i = 0; i < n; i++) {
if (p.charAt(i) == '*' && dp[0][i - 1]) {
dp[0][i + 1] = true;// 考虑了s和p均为空的情况,下标为i时对应dp中为i+1
}
}
// 正常情况
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (p.charAt(j) == s.charAt(i) || p.charAt(j) == '.') {
dp[i + 1][j + 1] = dp[i][j];
}
if (p.charAt(j) == '*') {
// 遇到‘*’,比较p的j-1字符与s的当前字符,不相等则比较p的j-2字符与s的当前字符
if (p.charAt(j - 1) != s.charAt(i) && p.charAt(j - 1) != '.') {
dp[i + 1][j + 1] = dp[i + 1][j - 1];
} else {
dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j - 1]);
}
}
}
}
// 最后返回是s下标为m-1,p下标为n-1的结果
return dp[m][n];
}