【LeetCode】141. Questões Avançadas da Lista Circular Ligada 142. Lista Circular Ligada II

 141. Lista Ligada Circular

Esta questão ainda é feita com o método clássico de ponteiro rápido e lento . Deixe o ponteiro rápido dar dois passos de cada vez e o lento um passo. Se houver um anel, eles definitivamente se encontrarão em algum nó dentro do anel. O pensamento tem algo a ver com o conhecimento da física. Se houver um anel, então, no processo de movimento relativo, pode ser equivalente ao ponteiro lento parado, e toda vez que o ponteiro rápido der um passo, ele definitivamente se encontrará no fim. Esta é também a condição para julgar que existe um anel.

Se não houver loop, o ponteiro rápido definitivamente será nulo no final quando estiver em movimento. Esta é a condição para julgar acíclico.

 código do algoritmo

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast!=null&&fast.next!=null) {

            fast = fast.next.next;
            slow = slow.next;

            if(fast == slow) {
                return true;
            }

        }

        return false;
        
    }
}

resultado da operação

 

142. Lista Circular Ligada II

Em comparação com a pergunta anterior, a pergunta anterior só precisa julgar se há um anel ou não, esta pergunta também retorna o primeiro nó da lista encadeada começando a entrar no anel com base na pergunta anterior. Retorna nulo se a lista encadeada for acíclica.

A ideia é adicionar um ponteiro para o nó principal quando for determinado que há um loop. Neste momento, deixe o ponteiro apontando para o ponto de encontro e o recém-adicionado (apontando para o nó principal) esses dois ponteiros continuem a usar a mesma "Velocidade" para voltar até "encontro" (apontando para o mesmo nó), o nó referido neste momento é o primeiro nó onde a lista encadeada começa a entrar no anel.

 código do algoritmo

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;

        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;

            if(fast == slow) {
                ListNode node = head;  //新加入一个指向头结点的指针
                while(node != slow) {
                    node = node.next;
                    slow = slow.next;
                }
                return node; //返回slow也行
            }
        }

        return null;
        
    }
}

resultado da operação

 

Acho que você gosta

Origin blog.csdn.net/m0_73381672/article/details/132066652
Recomendado
Clasificación