LeetCode每日一题,234. Palindrome Linked List
先看题目描述
大意就是给定一个链表,让我们判断它是否为回文链表
算法和思路
递归
这个思路参照了前几天做的题重排链表里的递归的算法
思路就是当给定一个链表后,若我们已知链表的头节点和尾节点,并且可以判断头节点和尾节点之间的部分是否为回文链表,那么这个问题就很好解决。于是就希望实现一个递归函数,可以判断中间部分是否是回文链表,并且可以返回尾节点。因此就想到构造这样一个递归函数:
- 若头节点和尾节点之间的部分是回文链表,则返回尾节点
- 若中间的部分不是回文链表,则返回 null
那么我们实现该函数以后,只需再对头节点和尾节点的值进行比较,然后返回 true 或 false 即可
快慢指针+反转后半部分链表
这个算法的效率没有上一个递归算法的运行效率高
整个流程可以分为以下五个步骤:
- 通过快慢指针找到前半部分链表的尾节点
- 反转后半部分链表
- 判断是否回文
- 恢复链表
- 返回结果
执行步骤一,我们可以计算链表节点的数量,然后遍历链表找到前半部分的尾节点
我们也可以使用快慢指针在一次遍历中找到:慢指针一次走一步,快指针一次走两步,快慢指针同时出发。当快指针移动到链表的末尾时,慢指针恰好到链表的中间。通过慢指针将链表分为两部分
若链表有奇数个节点,则中间的节点应该看作是前半部分
步骤二可以使用 206. 反转链表 问题中的解决方法来反转链表的后半部分
步骤三比较两个部分的值,当后半部分到达末尾则比较完成,可以忽略计数情况中的中间节点
步骤四与步骤二使用的函数相同,再反转一次恢复链表本身
算法源码
递归
1 | /** |
快慢指针+反转后半部分链表
1 | class Solution { |