Skip to content

Instantly share code, notes, and snippets.

@iJustErikk
Last active December 15, 2020 16:19
Show Gist options
  • Save iJustErikk/675ca9f2c36c9400e21c084b7326b3bd to your computer and use it in GitHub Desktop.
Save iJustErikk/675ca9f2c36c9400e21c084b7326b3bd to your computer and use it in GitHub Desktop.
updated for medium
const isPalindrome = (head) => {
// zero and single element lists are always symmetric
if (head === null || head.next === null) return true;
let fast = head;
let slow = head;
// fast pointer technique
// since fast traverses whole list and moves 2x as fast
// it makes sense how slow can be only halfway through
// if list is odd, fast will end up being not being null
// len(l) -> 2: s0 f0 s1 fnull
// len(l) -> 3: s0 f0 s1 f2
// len(l) -> 4: s0 f0 s1 f2 s2 fnull
while (fast && fast.next !== null) {
slow = slow.next;
fast = fast.next;
fast = fast.next;
}
const newHead = reverseFromTo(head, slow);
// makes odd length lists work
if (fast) {
// if odd, we do not want to compare the middle
slow = slow.next;
}
let first = newHead;
let second = slow;
while (second !== null) {
if (first.value !== second.value) return false;
first = first.next;
second = second.next;
}
return true;
}
// reverses linked list starting from head to stopAt exclusive
const reverseFromTo = (head, stopAt) => {
// I recommend trying 1, 2, 3 and 3 and walking through this algorithm
// to find that it will return 2 1 3
let current = head;
let previous = stopAt;
while (current !== stopAt) {
next = current.next;
current.next = previous;
previous = current;
current = next;
}
return previous;
}
// Utility
class ListNode {
constructor(value) {
this.value = value;
this.next = null;
}
}
const constructList = (arr) => {
let head = null;
let tail = null;
for (let item of arr) {
const newNode = new ListNode(item);
if (!head) {
head = newNode;
tail = newNode;
} else {
tail.next = newNode;
tail = newNode;
}
}
return head;
}
// Tests
const checkPalindromes = () => {
// should be true, true, false, true, false, true
const toCheck = [[], [3], [1, 3], [1, 1], [1, 2, 3], [1, 2, 1]];
const expections = [true, true, false, true, false, true];
toCheck.forEach((item, idx) => {
console.assert(isPalindrome(constructList(item)) === expections[idx]);
});
console.log("Passed test cases!")
};
checkPalindromes();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment