Proceso de aprendizaje de Xiaojie No. 1111. Profundidad de mosaico de paréntesis efectivos

La pregunta se transfiere del
propio LeetCode como un principiante del algoritmo para registrar el pensamiento sobre la pregunta de LeetCode. Sus ideas se refieren principalmente a soluciones oficiales y métodos de internautas.

Narrativa del tema

Definición de cadenas de corchetes válidas: para cada corchete izquierdo, se puede encontrar el corchete derecho correspondiente y viceversa. Para obtener detalles, consulte la sección "Cadenas de soporte válidas" al final de la pregunta.

Definición de profundidad de anidación: el número de cadenas de paréntesis efectivas anidadas, la profundidad (A) indica la profundidad de anidación de la cadena de paréntesis válida A. Para obtener detalles, consulte la sección "Profundidad de anidamiento" al final de la pregunta.

El tipo de cadena de caracteres de corchete efectivo y el método de cálculo de profundidad de anidamiento correspondiente se muestran en la siguiente figura:

Inserte la descripción de la imagen aquí

Proporcione una secuencia de "cadena de paréntesis válida", divídala en dos cadenas de paréntesis eficaces disjuntas, A y B, y minimice la profundidad de estas dos cadenas.

不相交:每个 seq[i] 只能分给 A 和 B 二者中的一个,不能既属于 A 也属于 B 。
A 或 B 中的元素在原字符串中可以不连续。
A.length + B.length = seq.length
深度最小:max(depth(A), depth(B)) 的可能取值最小。 

El esquema de división está representado por una respuesta de matriz de respuestas de longitud seq. De longitud, y las reglas de codificación son las siguientes:

answer[i] = 0,seq[i] 分给 A 。
answer[i] = 1,seq[i] 分给 B 。

Si hay varias respuestas que cumplen con los requisitos, simplemente devuelva cualquiera de ellas.

Ejemplo 1:

Entrada: seq = "(() ())"
Salida: [0,1,1,1,1,0]

Ejemplo 2

Entrada: seq = "() (()) ()"
Salida: [0,0,0,1,1,0,1,1]
Explicación: La respuesta a este ejemplo no es única.
Haga clic aquí para generar A = "() ()", B = "() ()", max (profundidad (A), profundidad (B)) = 1, y su profundidad es la más pequeña.
Al igual que [1,1,1,0,0,1,1,1], también es el resultado correcto, donde A = "() () ()", B = "()", max (profundidad (A), profundidad (B)) = 1.

Consejos:

1 < seq.size <= 10000

Cadena de soporte válida:

Para una cadena que consiste solo en "(" y ")", para cada corchete izquierdo, se puede encontrar el corchete derecho correspondiente, y viceversa.
Los siguientes casos también son cadenas de paréntesis válidas:

  1. Cadena vacía
  2. Conexión, puede escribirse como AB (A y B están conectados), donde A y B son cadenas de paréntesis válidas
  3. Anidado, se puede escribir como (A), donde A es una cadena de paréntesis válida

Profundidad de anidamiento:

Del mismo modo, podemos definir la profundidad de anidamiento (S) de cualquier cadena de paréntesis válida s:

  1. Cuando s está vacío, profundidad ("") = 0
  2. s es la conexión entre A y B, profundidad (A + B) = max (profundidad (A), profundidad (B)), donde A y B son cadenas de paréntesis válidas
  3. s es la situación de anidación, profundidad ("(" + A + ")") = 1 + profundidad (A), donde A es una cadena de paréntesis válida

Por ejemplo: "", "() ()" y "() (() ())" son cadenas de paréntesis válidas, y la profundidad de anidación es 0, 1, 2, respectivamente, mientras que ") (" y "((( ) ”No son cadenas de paréntesis válidas.

Fuente: LeetCode
Enlace: https://leetcode-cn.com/problems/maximum-nesting-depth-of-two-valid-parentheses-strings

Solución

1. Pila

seq = "(()())"
ans = []
d = 0
for c in seq:
    if c == '(':
        d += 1
        ans.append(d % 2)
    if c == ')':
        ans.append(d % 2)
        d -= 1
print(ans)

Resultado de salida:

[1, 0, 0, 0, 0, 1]

Esta solución se refiere a la solución oficial. La
idea es utilizar una variable para simular el tamaño de la pila de grabación y la variable d para registrar la profundidad de la pila. Atraviese la cadena. Cuando el carácter actual es "(", se inserta en la pila. Cuando el carácter actual es ")", aparece un "(". La variable d registra el número de "(". En este momento, utilizamos la profundidad de paridad de "(" Sexo, divídalos en dos grupos en promedio (es decir: d% 2).

2. Dos grupos consecutivos ((o) en diferentes grupos

seq = "(()())"
ans = [1]
for i in range(1, len(seq)):
    ans.append(1 - ans[i - 1]) if seq[i] == seq[i - 1] else ans.append(ans[i - 1])
print(ans)

Resultado de salida:

[1, 0, 0, 0, 0, 1]

Al pensar en el método uno, hemos obtenido que mientras dos grupos consecutivos (o) no estén divididos en el mismo grupo, entonces tenemos este método.
Al principio dividimos el primer "(" en una matriz impar (es decir: ans = [1]), y luego usamos un bucle para determinar si el segundo es el mismo que el primero. Si son iguales, luego se divide en otro grupo (es decir : Append (1-ans [i-1])), si es diferente, entonces colóquelo en el mismo grupo que antes (es decir: append (ans [i-1])).

3. Solución simplificada 1

seq = "(()())"
ans = []
for i, c in enumerate(seq):
    ans.append((i & 1) ^ (c == '('))
print(ans)

Resultado de salida:

[1, 0, 0, 0, 0, 1]

Simplificación del método uno
(i & 1) ^ (c == '('), el símbolo "^" no devuelve 1 en ambos lados, de lo contrario devuelve 0.
Debido a que es un paréntesis válido, su paridad numérica debe ser diferente, i 1. debe ser diferente. Luego use c es '(', su c == '(' también debe ser diferente, por lo que al final su valor (i & 1) ^ (c == '(') debe ser igual a 0 o 1 , Para lograr el propósito de dividirse en el mismo grupo.

10 artículos originales publicados · Me gusta0 · Visitas50

Supongo que te gusta

Origin blog.csdn.net/z55947810/article/details/105584995
Recomendado
Clasificación