A questão é transferida do
próprio LeetCode como iniciante do algoritmo para registrar o pensamento sobre a questão do LeetCode. Suas idéias se referem principalmente a soluções oficiais e métodos de internautas.
Narrativa do tópico
Definição de cadeias de colchetes válidas: Para cada colchete esquerdo, o colchete direito correspondente pode ser encontrado e vice-versa. Para detalhes, consulte a seção "Cordas de suporte válidas" no final da pergunta.
Definição de profundidade de aninhamento: o número de seqüências de parênteses efetivas aninhadas, a profundidade (A) indica a profundidade de aninhamento da sequência de parênteses válida A. Para detalhes, consulte a seção “Profundidade de nidificação” no final da pergunta.
O tipo de sequência de caracteres entre colchetes efetivo e o método de cálculo da profundidade de aninhamento correspondente são mostrados na figura a seguir:
Dê a você uma "seqüência de colchetes válida" seq, divida-a em duas cadeias de colchetes efetivas separadas, A e B, e minimize a profundidade dessas duas cadeias.
不相交:每个 seq[i] 只能分给 A 和 B 二者中的一个,不能既属于 A 也属于 B 。
A 或 B 中的元素在原字符串中可以不连续。
A.length + B.length = seq.length
深度最小:max(depth(A), depth(B)) 的可能取值最小。
O esquema de divisão é representado por uma resposta da matriz de respostas de length seq.length e as regras de codificação são as seguintes:
answer[i] = 0,seq[i] 分给 A 。
answer[i] = 1,seq[i] 分给 B 。
Se houver várias respostas que atendam aos requisitos, basta retornar qualquer uma delas.
Exemplo 1:
Entrada: seq = "(() ())"
Saída: [0,1,1,1,1,0]
Exemplo 2:
Entrada: seq = "() (()) ()"
Saída: [0,0,0,1,1,0,1,1]
Explicação: A resposta para este exemplo não é exclusiva.
Clique aqui para exibir A = "() ()", B = "() ()", max (profundidade (A), profundidade (B)) = 1, e sua profundidade é a menor.
Como [1,1,1,0,0,1,1,1], também é o resultado correto, onde A = "() () ()", B = "()", max (profundidade (A), profundidade (B)) = 1.
Dicas:
1 < seq.size <= 10000
Sequência de colchetes válida:
Para uma sequência composta apenas por "(" e ")", para cada colchete esquerdo, o colchete direito correspondente pode ser encontrado e vice-versa.
Os seguintes casos também são cadeias de parênteses válidas:
- String vazia
- Conexão, pode ser gravada como AB (A e B estão conectados), onde A e B são cadeias de parênteses válidas
- Aninhado, pode ser escrito como (A), onde A é uma cadeia de colchetes válida
Profundidade de aninhamento:
Da mesma forma, podemos definir a profundidade de aninhamento (S) de qualquer sequência de colchetes válida s:
- Quando s está vazio, depth ("") = 0
- s é a conexão entre A e B, profundidade (A + B) = max (profundidade (A), profundidade (B)), em que A e B são cadeias de parênteses válidas
- s é a situação de aninhamento, depth ("(" + A + ")") = 1 + depth (A), em que A é uma sequência de colchetes válida
Por exemplo: "", "() ()" e "() (() ())" são todas cadeias de parênteses válidas, e a profundidade do aninhamento é 0, 1, 2, respectivamente, enquanto ") (" e "(( ) ”Não são cadeias de parênteses válidas.
Fonte: LeetCode
Link: https://leetcode-cn.com/problems/maximum-nesting-depth-of-two-valid-parentheses-strings
Solução
1. Pilha
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 saída:
[1, 0, 0, 0, 0, 1]
Esta solução refere-se à solução oficial.A
idéia é usar uma variável para simular o tamanho da pilha de gravação e a variável d para registrar a profundidade da pilha. Atravesse a string. Quando o caractere atual é "(", ele é empurrado para a pilha. Quando o caractere atual é ")", um "(" é exibido. A variável d registra o número de "(". No momento, usamos a profundidade de paridade de "(" Sexo, divida-os em dois grupos em média (ou seja: d% 2).
2. Dois grupos consecutivos (ou) em grupos diferentes
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 saída:
[1, 0, 0, 0, 0, 1]
Pensando no método um, obtivemos que, enquanto dois grupos consecutivos (ou) não estão divididos no mesmo grupo, temos esse método.
Inicialmente, dividimos o primeiro "(" em uma matriz ímpar (ie: ans = [1]) e, em seguida, usamos um loop para determinar se o segundo é igual ao primeiro. Se eles são iguais, divida-o em outro grupo (ou seja, : Anexar (1-ans [i-1])), se for diferente, coloque-o no mesmo grupo de antes (ou seja: anexar (ans [i-1])).
3. solução simplificada 1
seq = "(()())"
ans = []
for i, c in enumerate(seq):
ans.append((i & 1) ^ (c == '('))
print(ans)
Resultado de saída:
[1, 0, 0, 0, 0, 1]
Simplificação do método um
(i & 1) ^ (c == '('), o símbolo "^" não retorna 1 em ambos os lados; caso contrário, retorna 0.
Como é um parêntese válido, sua paridade numérica deve ser diferente, ou seja, 1. deve ser diferente.Então, use c é '(', seu c == '(' também deve ser diferente, portanto, no final, seu valor (i & 1) ^ (c == '(')) deve ser igual a 0 ou 1 , Para atingir o objetivo de ser dividido no mesmo grupo.