DEV Community

Patrick Jones
Patrick Jones

Posted on • Edited on

3 2

Leetcode #234 - Palindrome Linked List

Problem: Given a singly linked list, determine if it is a palindrome.

Method 1: Create an array of values

The structure of a linked list doesn't provide access to the total size of the list. To get around this we can iterate over the list and push the node values on to an array. At that point we have access to the array's length and can use a single pointer i to compare values opposite to eachother in the array.

var isPalindrome = function(head) {
    let values = []
    // push all node values into an array
    while (head !== null) {
        values.push(head.val)
        head = head.next
    }
    // iterate over array and compare values
    for (let i = 0; i < values.length >> 1; i++) {
        // (values.length - i - 1) is our virtual pointer
        if (values[i] !== values[values.length - i - 1]) return false
    }
    return true
};
Enter fullscreen mode Exit fullscreen mode

The time and space complexity of this method are O(n)

Method 2: Reverse the Second Half in Place

We can use a fast and slow pointer to get to the center and the end of the list, respectively. Once we are able to determine the center, we use the slow pointer to re-link the second half of the list in reverse. I like to conceptualize this method as taking a snake and turning its tail into a head, resulting in a two headed snake with a tail (ListNode.next = null) in the middle.

var isPalindrome = function(head) {
    if (head === null || head.next == null) return true
    let slow = head
    let fast = head

    while (fast !== null && fast.next !== null) {
        fast = fast.next.next
        slow = slow.next
    }
    // if list length is odd, move slow over one to start
    // the second half of the list
    if (fast) {
        slow = slow.next
    }

    // reverse the second half of the list
    slow = reverse(slow)
    fast = head

    // check for palindromicity
    while (slow) {
        if (slow.val !== fast.val) {
            return false
        }
        slow = slow.next
        fast = fast.next
    }
    return true
}

function reverse(head) {
    let prev = null
    let next;
    while (head) {
        next = head.next
        head.next = prev
        prev = head
        head = next
    }
    return prev
}
Enter fullscreen mode Exit fullscreen mode

The time complexity is O(n) and space complexity is O(1) as we are not creating any extra arrays.

Image of Stellar post

How a Hackathon Project became a Web3 Startup 🚀

Ever wondered what it takes to build a web3 startup from scratch? In the Stellar Dev Diaries series, we follow the journey of a team of developers building on the Stellar Network as they go from hackathon win to getting funded and launching on mainnet.

Watch the video

Top comments (1)

Collapse
 
mallchel profile image
Sebastian Leukhin

This code is difficult to understand. Variable names, especially when goes like this: fast = head, and expressions like reverse(slow).
I think it would better to go to the end saving the prev node to prev property and when you achieve the end, you can just compare head and last.prev and go ahead until node links are the same. What do you think about it?

Neon image

Next.js applications: Set up a Neon project in seconds

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

👋 Kindness is contagious

Dive into this insightful write-up, celebrated within the collaborative DEV Community. Developers at any stage are invited to contribute and elevate our shared skills.

A simple "thank you" can boost someone’s spirits—leave your kudos in the comments!

On DEV, exchanging ideas fuels progress and deepens our connections. If this post helped you, a brief note of thanks goes a long way.

Okay