LeetCode打卡 (234. 判断回文链表的快慢指针超详细解析)

8 篇文章 0 订阅
5 篇文章 0 订阅

234. 回文链表

难度 简单

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?


打开网页 拿到题目 难度简单 我超勇的!

二话不说

就想到了方法一:遍历整条链表,逐个将值添加到ArrayList数组
用双指针前后比较,不等则输出false。
时间复杂度O(n)
空间复杂度O(n)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        List<Integer> vals = new ArrayList<>();
        ListNode currentNode = head;
        while (currentNode != null) {
            vals.add(currentNode.val);
            currentNode = currentNode.next;
        }
        int front = 0;
        int back = vals.size() - 1;
        while (front < back) {
            if (!vals.get(front).equals(vals.get(back))) {
                return false;
            }
            front++;
            back--;
        }
        return true;
    }
}

然后又想到能不能稍微优化一下,毕竟过于简单了。
于是我就想到判断一个回文数(就像上面判断复制数组),我们能不能不另造空间直接在链表上比呢?
于是,就有了将链表反转的思路
反转全部是不可能的,因为那样判断还是要另造空间。细想一下一个回文链表我们只要判断它的前半段反转再和后半段是否一样就可以了,当然,链表长度为奇数的话不用判断中间的值。

举例 1->2->3->2->1 前半段 反转后 的图
在这里插入图片描述
此时我们只要遍历逐个判断pre.val和p.val
那么问题来了,我们怎么才能把指针指向中间的位置,并且将前半段反转呢?


于是,我就想到了 == 方式二:快慢指针==
也就是给定两个指针分别是fast和slow
slow一次走一个
fast一次走两个
slow = slow.next
fast = fast.next.next
分析一下循环条件:
在这里插入图片描述
指针同颜色为同一步,fast走到底时slow刚好走到中间,并且此时是链长是奇数


那我们正好判断一下偶数链长情况:
在这里插入图片描述
fast到底时为空slow为链长中间偏右


于是判断条件可以是while(fast != null && fast.next != null)
接着就是反转链表了,可以注意到slow指针是一步一步往后走的,我们就可定义一个pres记录上一个slow,并定义一个pre记录pres的前一个。
最终代码如下:


class Solution {
    public boolean isPalindrome(ListNode node) {
        if (node==null||node.next==null) return true;
        ListNode fast = node;
        ListNode slow = node;
        ListNode pres = null;
        ListNode pre = null;
        while (fast!=null&&fast.next!=null){
            pres = slow;
            slow=slow.next;
            fast=fast.next.next;
            pres.next = pre;
            pre = pres;
        }
        if (fast!=null){
            slow=slow.next;
        }
        while (pres!=null){
            if (pres.val!=slow.val){
                return false;
            }
            pres = pres.next;
            slow=slow.next;
        }
        return true;
    }
}

这样的处理使得我们没有用到额外的空间即空间复杂度优化到了O(1),而时间复杂度还是O(n).
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值