LeetCode《初级算法》链表之回文链表 -- JavaScript

498 阅读3分钟

题目

题目链接:leetcode-cn.com/leetbook/re…

image.png

题解


1、借助数组

前面字符串的题目中有一题是验证回文串,而这题是验证回文链表,我们可以用一个数组将链表的所有值存下来,然后再使用双指针验证是否是回文数组;

/**
 * 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}
 */
var isPalindrome = function(head) {

    let temp = head;
    let arr = [];
    let front = 0,
        rear = 0;

    while(temp != null) {

        arr.push(temp.val);
        
        temp = temp.next;
    }

    rear = arr.length - 1;

    while(rear >= front) {

        if(arr[rear] ^ arr[front]) { 
            return false;
        }
        rear--;
        front++;
        
    }

    return true;

};

2、先获取链表长度,再递归

借助辅助数组固然方便,但其空间复杂度也达到了 o(n),接下来不使用辅组数组,直接对链表操作;

/**
 * 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}
 */
var isPalindrome = function(head) {

    let len = 0,
        half = 0;
    let temp = head;
    
    let flag = false;
    let isodd = false;

    // 求链表长度
    while(temp) {

        len++;
        temp = temp.next;
    }

    half = Math.ceil(len/2); 

    if(len%2 === 1) {
        isodd = true;
    }
		// 递归函数
    function compare(head,half) { // 这里的递归函数使用了全局变量,在其它地方复用这个递归函数

        if(half === 0) {

            return head;
        }

        const h = compare(head.next,half - 1);

        if(half === 1 && isodd) { // 通过 isodd 这个全局变量来判断链表是否是奇数
            return h;
        }

        if(head.val !== h.val) {

                flag = true; // 使用 flag 这个全局变量来标识在 递归 的过程中链表对称位置上的元素是否有不  相等的
        }
       

        return h.next;

    }

    compare(head,half); 

    if(flag) {
        return false;
    }
    
    return true;

};

上面的代码中的递归函数因为使用了全局变量,所以递归函数将无法被复用在其它地方,下面给出可以复用的递归函数(通过向递归函数传递对象来实现);

/**
 * 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}
 */
var isPalindrome = function(head) {

    let len = 0,
        half = 0;
    let temp = head;

    let flag = {flag:false};
    let isodd = false;

    // 求链表长度
    while(temp) {

        len++;
        temp = temp.next;
    }

    half = Math.ceil(len/2); 

    if(len%2 === 1) {
        isodd = true;
    }


    // 递归函数
    function compare(head,half,isodd,flag) { // 改成可以复用的形式~,将 flag 改成对象传进去;

        if(half === 0) {

            return head;
        }

        const h = compare(head.next,half - 1,isodd,flag);

        if(half === 1 && isodd) { // 通过 isodd 这个全局变量来判断链表是否是奇数
            return h;
        }

        if(head.val !== h.val) {

                flag.flag = true; // 使用 flag 这个全局变量来标识在 递归 的过程中链表对称位置上的元素是否有不相等的
        }
       

        return h.next;

    }

    compare(head,half,isodd,flag);  

    if(flag.flag) {
        return false;
    }
    
    return true;

};

全量比较 n 次

上面两个递归算法使用的递归都只是链表的前半段和后半段比较,比较的次数为 n/2 ,这样就会需要考虑复杂的边界条件,即要找出中间位置,并且要在中间位置开始比较;

链表的前半段与后半段对称,这是回文链表的定义;链表反转后和原链表相等,这也是回文链表的定义;

因此可以写比较 n 次的算法,这种算法相对于比较 n/2 次的算法更好写;

/**
 * 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}
 */
var isPalindrome = function(head) {

    
    let temp = head;
    let flag = false;

    function compare(head,temp) {

        if(head === null){
            return temp;
        }

        const t = compare(head.next,temp);

        if(t.val !== head.val) {
            flag = true;
        }

        return t.next;

    }


    compare(head,temp);

    if(flag) {
        return false;
    }
    return true;
};



大家如果有更好的思路和解法,欢迎大家一起来讨论啊~

这是使用 JavaScript 对 LeetCode《初级算法》的每道题的总结和实现的其中一篇,汇总篇在这里:

juejin.cn/post/700669…