判断链表是否为回文链表 NC96

方法一:利用数组(栈)

遍历链表,用数组把数据存下来,然后再进行一次遍历,同时用数组反向地与之比较,这样就可以判断是否回文。这个方法时间复杂度是O(n)

  • pop()   移除数组的最后一项,返回移除的项
  • shift()  移除数组的第一项,返回移除项
var isPalindrome = function (head) {
    let nums = [];
    while (head) {
        nums.push(head.val);
        head = head.next;
    }
    while (nums.length > 1) {  //注意是大于1
        if (nums.pop() != nums.shift()) 
            return false;
    }
    return true;
};

 

方法二:快慢指针(双指针) 

时间复杂度O(n) 空间复杂度O(1)

思路:利用快慢指针p和q,初始时均指向头结点。之后慢指针q每走一步,快指针走两步。当快指针走到链表的尾部时,慢指针所指向的结点即为中间结点。这时等于把链表劈成了两半,然后把后半部分链表逆置,最后依次比较前半部分链表和逆置后的链表即可。

示意图
原始输入如下
在这里插入图片描述
我们调整链表之后

在这里插入图片描述
从head1与head2处开始遍历,如果在遍历的过程中发现不一致情况,直接返回false,如果直到有任意一方为空都没有不一致现象,那么就返回true。
最后记得调整回去。

var isPalindrome2 = function(head) {
    let slow = head, fast = head;
    while(fast && fast.next){
        slow = slow.next;
        fast = fast.next.next;
    }
    //反转后半段,这里跟之前反转链表的题一样,得到的
    let reverse = null;
    while(slow !== null){
        let tmp = slow.next;
        slow.next = reverse;
        reverse = slow;
        slow = tmp;
    }  //到这里,reverse就是反转好的后半部分链表
    // 将反转好的链表和原链表的前半部分依次进行值的比较
    while(reverse !== null){
        if(reverse.val !== head.val) 
            return false;
        reverse = reverse.next;
        head = head.next;
    } 
    return true;
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值