Prefácio
Atualize as postagens de escovação na forma de tópicos especiais. Bem-vindo a aprender a escovar comigo. Acredite em mim, sua persistência certamente trará ganhos inesperados. Cada pergunta fornecerá uma resposta simples, se você tiver uma abordagem mais elegante, bem-vindo para fornecer orientações, obrigado
[Descrição do tópico]
【Afirmação】
Entrada: o nó principal de uma lista circular unida individualmente e o número relatado m.
Retorno: O último nó sobrevivente, e este nó forma uma lista circular unida por si só, e todos os outros nós são excluídos.
【Dificuldade】
Táxi: ★ ☆☆☆
【responda】
Método 1: a complexidade do tempo é O (n * m)
Este problema é bastante simples se você não considerar a complexidade do tempo. Basta percorrer a lista ligada circular e excluir um nó toda vez que m nós forem percorridos. É suficiente saber que há apenas um nó restante na lista ligada.
código mostrado abaixo
1 //时间复杂度为O(n*m)的解决方法
2 public static Node josephusKill(Node head, int m) {
3 if(head == null || m < 1)
4 return head;
5 Node last = head;
6 //定位到最后一个节点
7 while (head.next != last) {
8 head = head.next;
9 }
10 int count = 0;
11 while (head.next != head) {
12 if (++count == m) {
13 head.next = head.next.next;
14 count = 0;
15 } else {
16 head = head.next;
17 }
18 }
19 return head;
20 }
Como alguns telefones celulares podem ter caracteres truncados, postarei fotos aqui:
A complexidade de tempo desse método é O (n * m). A complexidade do tempo é usada como uma solução abaixo.
Método 2: a complexidade do tempo é O (n)
A dificuldade deste método é:
Escola: ★★★ ☆
Podemos numerar os nós da lista ligada circular. Se o número de nós na lista ligada for n, comece com o nó principal e numerar sequencialmente os nós, ou seja, o nó principal é 1, o próximo nó é 2 e o último nó é n.
Usamos f (n) para denotar que quando o comprimento da lista ligada circular é n, o número de sobreviventes é f (n). Obviamente, quando n = 1, f (n) = 1. Se pudermos encontrar a relação entre f (n) ef (n-1), podemos resolvê-la de forma recursiva. Presumimos que o número de pessoas seja n, e aqueles que se reportarem a m cometerão suicídio. Então o número inicial é
…
m - 2
m - 1
m
m + 1
m + 2
…
Após uma exclusão, o nó numerado m é excluído. Após a exclusão, restam apenas n-1 nós. A relação de conversão do número antes e depois da exclusão é:
Antes de deletar --- Depois de deletar
… ---…
m - 2 --- n - 2
m - 1 --- n - 1
m ---- Nenhum (porque o número foi excluído)
m + 1 --- 1 (porque contarei a partir daqui na próxima vez)
m + 2 ---- 2
… ----…
Existem apenas n-1 nós no novo anel. E os nós numerados m + 1, m + 2, m + 3 tornam-se os nós numerados 1, 2, 3 no novo anel.
Assumindo que antigo é o número do nó antes da exclusão e novo é o número após a exclusão de um nó, a relação entre o antigo e o novo é antigo = (novo + m-1)% n + 1.
Nota: Algumas pessoas podem se perguntar por que não é antigo = (novo + m)% n? Principalmente porque a numeração começa em 1, não em 0. Se new + m == n, o resultado final do cálculo será old = 0. Tão antigo = (novo + m-1)% n + 1.
Dessa forma, obtemos a relação entre f (n) ef (n-1), ef (1) = 1. Portanto, podemos fazer isso de forma recursiva.
código mostrado como abaixo:
1 //时间复杂度为O(n)
2 public static Node josephusKill2(Node head, int m) {
3 if(head == null || m < 1)
4 return head;
5 int n = 1;//统计一共有多少个节点
6 Node last = head;
7 while (last.next != head) {
8 n++;
9 last = last.next;
10 }
11 //直接用递归算出目的编号
12 int des = f(n, m);
13 //把目的节点取出来
14 while (--des != 0) {
15 head = head.next;
16 }
17 head.next = head;
18 return head;
19 }
20
21 private static int f(int n, int m) {
22 if (n == 1) {
23 return 1;
24 }
25 return (f(n - 1, m) + m - 1) % n + 1;
26 }
Código da imagem:
Expansão do problema
Para a pergunta anterior, suponha que seja para deletar o número do nó K? Como resolver isso?
responda
Backstage responder, responder 3, obter resposta
Passado
[Problema de lista vinculada] Exclua o nó intermediário de uma lista unicamente vinculada
[Problema de lista vinculada] Como reverter elegantemente uma lista unida individualmente
[Problema de lista vinculada] Exclua o nó K na lista unicamente vinculada
[Combate de algoritmo] Gerar uma matriz de valores máximos de janela