Given a singly linked list, determine if it is a palindrome.

Example 1:

Input: 1->2
Output: false

Example 2:

Input: 1->2->2->1
Output: true

Follow up:
Could you do it in O(n) time and O(1) space?

这道题让我们判断一个链表是否为回文链表,LeetCode 中关于回文串的题共有六道,除了这道,其他的五道为 Palindrome Number,Validate Palindrome,Palindrome Partitioning,Palindrome Partitioning II 和 Longest Palindromic Substring。链表比字符串难的地方就在于不能通过坐标来直接访问,而只能从头开始遍历到某个位置。那么根据回文串的特点,我们需要比较对应位置的值是否相等,一个非常直接的思路就是先按顺序把所有的结点值都存入到一个栈 stack 里,然后利用栈的后入先出的特性,就可以按顺序从末尾取出结点值了,此时再从头遍历一遍链表,就可以比较回文的对应位置了,若不同直接返回 false 即可,参见代码如下:

解法一:

class Solution {
public:bool isPalindrome(ListNode* head) {ListNode *cur = head;stack<int> st;while (cur) {st.push(cur->val);cur = cur->next;}while (head) {int t = st.top(); st.pop();if (head->val != t) return false;head = head->next;}return true;}
};

我们也可以用迭代的形式来实现,此时需要使用一个全局变量结点 cur,先初始化为头结点,可以有两种写法,一种写在函数外面的全局变量,或者是在递归函数的参数中加上引用,也表示使用的是全局变量。然后对头结点调用递归函数,在递归函数中,首先判空,若为空则直接返回 true,否则就对下一个结点调用递归函数,若递归函数返回 true 且同时再当前结点值跟 cur 的结点值相同的话,就表明是回文串,否则就不是,注意每次 cur 需要指向下一个结点,参见代码如下:

解法二:

class Solution {
public:bool isPalindrome(ListNode* head) {ListNode *cur = head;return helper(head, cur);}bool helper(ListNode* node, ListNode*& cur) {if (!node) return true;bool res = helper(node->next, cur) && (cur->val == node->val);cur = cur->next;return res;}
};

其实上面的两种解法重复比较一些结点,因为只要前半个链表和后半个链表对应值相等,就是一个回文链表,而并不需要再比较一遍后半个链表,所以我们可以找到链表的中点,这个可以用快慢指针来实现,使用方法可以参见之前的两篇 Convert Sorted List to Binary Search Tree 和 Reorder List,使用快慢指针找中点的原理是 fast 和 slow 两个指针,每次快指针走两步,慢指针走一步,等快指针走完时,慢指针的位置就是中点。我们还需要用栈,每次慢指针走一步,都把值存入栈中,等到达中点时,链表的前半段都存入栈中了,由于栈的后进先出的性质,就可以和后半段链表按照回文对应的顺序比较了,参见代码如下:

解法三:

class Solution {
public:bool isPalindrome(ListNode* head) {if (!head || !head->next) return true;ListNode *slow = head, *fast = head;stack<int> st{{head->val}};while (fast->next && fast->next->next) {slow = slow->next;fast = fast->next->next;st.push(slow->val);}if (!fast->next) st.pop();while (slow->next) {slow = slow->next;int tmp = st.top(); st.pop();if (tmp != slow->val) return false;}return true;}
};

这道题的 Follow up 让我们用 O(1) 的空间,那就是说我们不能使用 stack 了,那么如何代替 stack 的作用呢,用 stack 的目的是为了利用其后进先出的特点,好倒着取出前半段的元素。那么现在不用 stack 了,如何倒着取元素呢。我们可以在找到中点后,将后半段的链表翻转一下,这样我们就可以按照回文的顺序比较了,参见代码如下:

解法四:

class Solution {
public:bool isPalindrome(ListNode* head) {if (!head || !head->next) return true;ListNode *slow = head, *fast = head;while (fast->next && fast->next->next) {slow = slow->next;fast = fast->next->next;}ListNode *last = slow->next, *pre = head;while (last->next) {ListNode *tmp = last->next;last->next = tmp->next;tmp->next = slow->next;slow->next = tmp;}while (slow->next) {slow = slow->next;if (pre->val != slow->val) return false;pre = pre->next;}return true;}
};

Githbu 同步地址:

https://github.com/grandyang/leetcode/issues/234

类似题目:

Palindrome Number

Validate Palindrome

Palindrome Partitioning

Palindrome Partitioning II

Longest Palindromic Substring

Reverse Linked List

参考资料:

https://leetcode.com/problems/palindrome-linked-list/

https://leetcode.com/problems/palindrome-linked-list/discuss/64501/Java-easy-to-understand

https://leetcode.com/problems/palindrome-linked-list/discuss/148220/Javathe-clear-method-with-stack

https://leetcode.com/problems/palindrome-linked-list/discuss/64490/My-easy-understand-C%2B%2B-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

转载于:https://www.cnblogs.com/grandyang/p/4635425.html

[LeetCode] 234. Palindrome Linked List 回文链表相关推荐

  1. 234. Palindrome Linked List 回文链表

    请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复 ...

  2. LeetCode Palindrome Linked List (回文链表)

    题意:给个单链表,判断是否为回文. 思路:有点BT,处理不好都是死循环.一般思路是,二分查找中心点,根据奇偶个元素,反置前半部分,再判断是否回文,再恢复前半部分. 步骤: (1)在二分查找中心点时判断 ...

  3. 【回文串7】LeetCode 234. Palindrome Linked List

    LeetCode 234. Palindrome Linked List Solution1:我的答案 一遍过,哈哈哈! /*** Definition for singly-linked list. ...

  4. LeetCode 234. Palindrome Linked List

    题目: Given a singly linked list, determine if it is a palindrome. 思路: 给定一个链表,判断它是不是回文链表 根据链表的奇偶分情况,然后 ...

  5. [LeetCode] 234. Palindrome Linked List_Easy tag: Linked List

    Given a singly linked list, determine if it is a palindrome. Example 1: Input: 1->2 Output: false ...

  6. LeetCode 234 Palindrome Linked List

    Given a singly linked list, determine if it is a palindrome. 思路: 回文结构从后向前遍历与从前向后遍历的结果是相同的,可以利用一个栈的结构 ...

  7. [swift] LeetCode 234. Palindrome Linked List

    Given a singly linked list, determine if it is a palindrome. Follow up: Could you do it in O(n) time ...

  8. LeetCode之Palindrome Number(回文数)

    1.题目 Determine whether an integer is a palindrome. Do this without extra space. 2.代码实现 代码实现1 public ...

  9. 【LeetCode】【HOT】234. 回文链表(存入数组)

    [LeetCode][HOT]234. 回文链表 文章目录 [LeetCode][HOT]234. 回文链表 package hot;import java.util.ArrayList; impor ...

最新文章

  1. 注意,ruby循环体定义的变量在结束时后,变量还存在
  2. 红茶一杯话Binder(传输机制篇_下)
  3. 好久不见(致win7)
  4. Repeater的嵌套结合用户控件的使用
  5. ubuntu制作usb启动盘
  6. 额!Java中用户线程和守护线程区别这么大?
  7. oracle关联分组查询,oracle中关联查询、分组查询
  8. 初中在线测试软件,关注中学生 心理测试工具上线!
  9. Go语言基础(一)——HelloWorld
  10. Windows查看端口占用
  11. java列表展开折叠,Android在开发中的实用技巧之ExpandableListView简单实现商品列表折叠...
  12. goland 注释模板_Java程序员简历模板,怎样才是一份好的技术简历
  13. 非常哇塞的 Spring Boot 性能优化长文
  14. 6.再来一题除法算术题
  15. element 日期选择器不能选择当天日期以后的日期
  16. mac忘了密码怎么办_如果忘记Mac密码该怎么办
  17. 大数据在保险应用场景
  18. chrome浏览器安全检查_为您的Chrome浏览器检查皮肤
  19. 【我的区块链之路】- 谈一谈IPFS原理及玩法
  20. navicat怎么备份数据和同步两个数据库

热门文章

  1. 《父亲家书》终篇:来京探望儿子之后
  2. java网络编程_Java网络编程进阶:通过JSSE创建安全的数据通信
  3. scrum回顾_133. 你最重要:2020版Scrum指南解读
  4. Oracle 复制一条 改主键,在一个表中复制一条同样的记录到同一个表中,只修改主键内容(200分)...
  5. php保存ppt,ppt怎么保存到电脑桌面?
  6. oracle动一下卡一下,记录一次Oracle很卡事件
  7. 服务超时时间如何设置、如何对超时时间治理、超时设计原则一文揭秘!
  8. sunny底层android,Android网络通信概述
  9. mysql小鲸鱼_杀死一只小鲸鱼
  10. 大数据产品开发流程规范_华为内部资料流出!揭秘华为数据湖:3大特点、6个标准、入湖流程...