【LeetCode】算法详解#13 ---回文链表
1.题目介绍
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
提示:
- 链表中节点数目在范围
[1, 105]
内 0 <= Node.val <= 9
2.解决思路
题目需求是判断一个链表是否是回文链表。在以往解决这类问题时,我们可以通过直接取中点然后操作一半的内容即可实现。但是这个题目中我们并不知道链表的长度,只知道头结点和下一个相邻节点,以此类推。所以要完成这个需求,我们只能想出另一种方式完成类似的过程。这里我推荐一种快慢指针的做法,即通过快慢指针找到链表的中点(快指针一次两步,慢指针一次一步,快指针到尾节点时慢指针此时指向链表中点),然后我们此时就可以使用一半链表对另一半链表进行比对得出结果
3.步骤讲解
1.首先创建一个主方法isPalindrome用于执行大体流程
2.判断头结点是否为null,为null则直接返回true
3.使用快慢指针寻找链表中点,创建findMid方法,传入头结点,定义慢指针slow,快指针fast同时指向头结点。当快指针下一个节点不为null且下下个节点也不为null时,慢指针移动一步,快指针移动两步。循环退出时表示快指针遍历到了尾节点,此时慢指针指向的节点就是中点,将慢指针返回。
4.将中点的下一个节点作为起始节点,把后一半链表进行反转,创建reverse方法,传入目标起始节点,利用双指针将链表翻转(与上一篇【LeetCode】算法详解#12 ---反转链表-CSDN博客类似),最终将反转之后的链表的头结点返回。
5.建立循环,两个子链表的下一个节点都不为空时,不断遍历比较节点值是否相同,在遍历结束之前如果有一个值不相同,表示该链表不是回文链表,返回false。否则返回true
4.代码展示
public class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public boolean isPalindrome(ListNode head) {if (head == null){return true;}//快慢指针找中点ListNode mid = findMid(head);//翻转链表ListNode reverse = reverse(mid.next);//比较两部分值是否相同while (head != null && reverse != null){if (head.val != reverse.val){return false;}head = head.next;reverse = reverse.next;}return true;}public ListNode reverse(ListNode mid){ListNode prev = null;ListNode curr = mid;while (curr != null) {ListNode nextTemp = curr.next;curr.next = prev;prev = curr;curr = nextTemp;}return prev;}public ListNode findMid(ListNode head){ListNode slow = head;ListNode fast = head;while (fast.next != null && fast.next.next != null){slow = slow.next;fast = fast.next.next;}return slow;}
5.执行结果
在leetcode中测试用例平均耗时5ms
内存分布58.25MB