Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
- Linked List
- [Task #34](src/neetcode/linked-list/reversed-linked-list) – _Reversed Linked List_ - _[check the task](https://neetcode.io/problems/reverse-a-linked-list)_
- [Task #35](src/neetcode/linked-list/merge-two-sorted-lists) – _Merge Two Sorted Lists_ - _[check the task](https://neetcode.io/problems/merge-two-sorted-linked-lists)_
- [Task #36](src/neetcode/linked-list/linked-list-cycle) – _Linked List Cycle_ - _[check the task](https://neetcode.io/problems/linked-list-cycle-detection)_

[BigFrontEnd - JavaScript Coding Questions](https://bigfrontend.dev/problem)
- [1. implement curry()](src/bigfrontend/javascript/curry) - _Curry Function_ - [check the task](https://bigfrontend.dev/problem/implement-curry)
Expand Down
50 changes: 50 additions & 0 deletions src/neetcode/linked-list/linked-list-cycle/solution.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { createList, ListNode } from '../common';
import { hasCycle } from './solution';

describe('Linked List Cycle | NeetCode | RoadMap | Testcases', () => {
test('#1 Returns false for an empty list', () => {
expect(hasCycle(null)).toBe(false);
});

test('#2 Returns false for a list without a cycle', () => {
const head = createList([1, 2, 3, 4]);

expect(hasCycle(head)).toBe(false);
});

test('#3 Returns false for a single node without a cycle', () => {
const head = new ListNode(1);

expect(hasCycle(head)).toBe(false);
});

test('#4 Detects a cycle that starts in the middle of the list', () => {
const first = new ListNode(3);
const cycleStart = new ListNode(2);
const third = new ListNode(0);
const tail = new ListNode(-4);

first.next = cycleStart;
cycleStart.next = third;
third.next = tail;
tail.next = cycleStart;

expect(hasCycle(first)).toBe(true);
});

test('#5 Detects a cycle that points back to the head', () => {
const first = new ListNode(1);
const second = new ListNode(2);
first.next = second;
second.next = first;

expect(hasCycle(first)).toBe(true);
});

test('#6 Detects a self-referencing node', () => {
const head = new ListNode(1);
head.next = head;

expect(hasCycle(head)).toBe(true);
});
});
21 changes: 21 additions & 0 deletions src/neetcode/linked-list/linked-list-cycle/solution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ListNode } from '../common';

/**
* @param {ListNode} head - the beginning of a linked list
* @return {boolean} - `true` if there is a cycle in the linked list, `false` otherwise.
*/
export const hasCycle = (head: ListNode | null): boolean => {
let slow: ListNode | null = head;
let fast: ListNode | null = head;

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

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

return false;
};
Loading