234. 回文链表 JavaScript实现

234. 回文链表

题目链接

一、将值复制到数组中后用双指针法

1、为什么要将值复制到数组中?

因为在链表中访问一个特定的节点需要O(n),而这个题目是需要遍历一半链表数量的节点,前后进行比较。
234. 回文链表 JavaScript实现_第1张图片

2、时间复杂度

234. 回文链表 JavaScript实现_第2张图片

3、代码实现

var isPalindrome = function(head) {
    // 利用数组存储链表的值
    let vals = [];
    while(head){
       vals.push(head.val);
       head = head.next;
    }

    // 利用双指针进行前后元素的比较
    for(let i=0,j=vals.length-1; i<j; i++,j--){
        if(vals[i] != vals[j]){
            return false
        }
    }
    return true;
};

二、快慢指针

避免使用 O(n)O(n) 额外空间的方法就是改变输入。我们可以将链表的后半部分反转(修改链表结构),然后将前半部分和后半部分进行比较(反转后的前后链表应该是一样的)。

1、找到中间节点,将链表拆分
2、反转后半部分链表
3、判断回文,前后链表是否相等
4、恢复链表
5、返回结果

// 中间节点,注意这里当有两个中间节点时,返回第一个节点。所以循环条件改变
var findMid = function(head){
    let slow=head, fast=head;
    while (fast.next !== null && fast.next.next !== null){
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow;
}

// 反转链表
var reverse = function(head){
    let pre = null, cur = head;
    while(cur){
        let temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
}

// 判断回文
var isPalindrome = function(head) {
    // 1、找到中间节点,将链表拆分
    let mid = findMid(head);

    // 2、反转后半部分链表
    let second = reverse(mid.next);


    // 3、判断回文
    while(second){
        if(head.val != second.val){
            return false
        }
        head = head.next;
        second = second.next;
    }


    // 4、还原链表并返回结果
    mid.next = reverse(second);
    return true;
};

在这里插入图片描述

你可能感兴趣的:(leetcode刷题,#,链表,链表,javascript,leetcode,数据结构,算法)