'On the Leetcode Palindrome problem (number 234), why is my JavaScript solution not passing all the test cases?

I'm working on the palindrome question, and failing the [1,2] test case. Below is my code:

var isPalindrome = function(head) {
    var listLength = head.length ? head.length : 0;
    if (listLength === 0 || listLength === 1) return true;
    
    var curNode = head[0];
    var tailNode = head[listLength - 1];
    if (listLength === 2) {
//         if (curNode === tailNode) return true;

//         return false;
        return curNode === tailNode;
    }

    if (curNode !== tailNode) return false;

    head.shift();
    head.pop();

    return (isPalindrome(head));
};

When I run the test case in vscode on my device, I get false for [1,2] (which is the expected result) but the uploaded version on leetcode is failing that test and returning true instead. I have no clue why. My solution is by no means the best solution but I tried a handful of tests on my local and it seemed to get the job done. Any advice on how to fix this, or insight as to why I'm failing the test case on leetcode?

Initially I thought it was the way I structured my conditional when listLength is 2, but I changed that to something I'm sure would work and it didn't change the outcome.

edit: link to leetcode question https://leetcode.com/problems/palindrome-linked-list/



Solution 1:[1]

As @JoshuaWood pointed out, I was operating under the assumption that my list had array properties native to JavaScript arrays, but this is an incorrect way of viewing the problem. I had to quite literally handle the list with the pointer and data they provided me. (see definition below)

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {boolean}
 */

Once I realized I wouldn't be able to use any array properties, and just use the properties given to me in the definition above, I was able to reformat my solution and come up with this:

var isPalindrome = function(head) {
    let curr = head;
    var len = 0;
    let last = null;
    let secondToLast = null;
    if (curr.val !== null) len = 1;
    if (curr && curr.next === null) return true;
    while (curr.next !== null) {
        len++;
        secondToLast = curr;
        curr = curr.next;
    }
    last = curr;
    if (len === 2) {
        if (head.val === last.val) return true;
        
        return false;
    }
    if (head.val === last.val) {
        secondToLast.next = null;
        last.val = null;
        last = null;
        return isPalindrome(head.next);
    } else {
        return false;
    }
}

Basically I can navigate to the end of the list, store what's at the end, compare it to the beginning, and pop off those values if they are equal. If they're not equal, then the list is not a Palindrome. If they are, then I iterate to the next entry in the list and pop off the end. This continues until you either reach a list with only 1 or 2 left, does the final comparison if there are two, or simply returns true if there's only one node left since that node will be equal to itself.

Hope this helps! Once I realized that of course they wouldn't have array properties, it all made a lot more sense.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 AliveSquare