Processo de aprendizagem de Xiaojie nº 1111. Profundidade do mosaico de colchetes efetivos

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:

Insira a descrição da imagem aqui

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:

  1. String vazia
  2. 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
  3. 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:

  1. Quando s está vazio, depth ("") = 0
  2. 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
  3. 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.

Publicado 10 artigos originais · Curtidas0 · Visitas50

Acho que você gosta

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