Na vstupu je linked list (spojový seznam). Tvým úkolem je zjistit, zda se v něm nachází cyklus (některý z nodů míří na předchozí node).

Linked list bez cyklu

flowchart LR
    node1((0)) -->
    node2((1)) -->
    node3((2)) --> 
    node4((3)) --> 
    node5((4))
  

Linked list s cyklem

flowchart LR
    node1((0)) -->
    node2((1)) -->
    node3((2)) --> 
    node4((3)) --> 
    node5((4)) --> node3
  

Detaily:

  • Pokud obsahuje pouze jeden prvek, není v něm cyklus
  • Pokud neobsahuje žádný prvek, není v něm cyklus
class ListNode {
    val: number
    next: ListNode | null
    constructor(val?: number, next?: ListNode | null) {
        this.val = (val === undefined ? 0 : val)
        this.next = (next === undefined ? null : next)
    }
}
 
function hasCycle(head: ListNode | null): boolean {
    // Doplň tělo funkce
};

Testy - správného chování

describe("Is linked list circular", () => {
    test("Without cycle", () => {
        const node1 = new ListNode(2);
        const node2 = new ListNode(2, node1);
        const node3 = new ListNode(3, node2);
        const node4 = new ListNode(4, node3);
        const head = new ListNode(5, node4);
 
        expect(hasCycle(head)).toStrictEqual(false);
    });
 
    test("With a cycle back to start", () => {
        const node1 = new ListNode(2);
        const node2 = new ListNode(2, node1);
        const node3 = new ListNode(3, node2);
        const node4 = new ListNode(4, node3);
        const head = new ListNode(5, node4);
 
        // Cycle
        node1.next = head;
 
        expect(hasCycle(head)).toStrictEqual(true);
    });
});

Pokud nevíš, jak na optimální řešení, tak to zkus vyřešit jakýmkoli způsobem. Potom si přečti, jak funguje optimální algoritmus a zkus ho naprogramovat.