美文网首页LeetCode 之路
LeetCode 234——回文链表

LeetCode 234——回文链表

作者: seniusen | 来源:发表于2018-10-13 21:23 被阅读13次

1. 题目

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

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

输入: 1->2->2->1
输出: true

进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

2. 思路

定义快慢两个指针,寻找中间结点,同时在慢指针移动的过程中反转前半部分子链表。当找到中间结点时,再分别向前向后比较前后两个子链表的每一个结点值是否相同。

  • 偶数结点情况如下


    3.png
4.png 5.png 6.png
  • 此时,我们分别得到了以 slow 为头指针的前半部分子链表和以 p2 为头指针的后半部分子链表。由于中间结点偏向后边,所以我们需要先比较最中间的两个结点(此处为 2 和 3 结点),然后再依次向两边循环比较直到到达子链的链尾。

  • 再来看奇数结点的情况

7.png 8.png
  • 奇数个结点时,我们依然可以分别得到以 slow 为头指针的前半部分子链表和以 p2 为头指针的后半部分子链表。此时,由于 slow 指向的中间结点无须比较,我们只需从 slow 后面第一个结点和 p2 指向的结点开始循环向两边比较即可(此处为 2 和 4 结点)
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        
        if (head == NULL || head->next == NULL)     // 空链或只有一个结点,返回 true
        {
            return true;            
        }
        
        else
        {
            /* 此为反转链表的三个指针,slow 即代表 p1 */
            ListNode* slow = head;           // 慢指针指向第一个结点
            ListNode * p2 = slow->next;      // 第二个结点
            ListNode * p3 = p2->next;        // 第三个结点
            
            ListNode* fast = head;           // 快指针指向头结点

            // 奇数结点快指针指向最后一个结点结束
            // 偶数结点快指针指向 NULL 结束
            while(fast && fast->next)   
            {
                p3 = p2->next;
                fast = fast->next->next;    // 快指针前进两步
                p2->next = slow;            // 反转链表
                slow = p2;                  // 慢指针前进一步
                p2 = p3;
            }

            head->next = NULL; // 处理前半部分子链的尾节点

            // 偶数结点
            if(!fast)
            {
                // 先比较 slow 后的两个结点是否相同
                if (slow->val == slow->next->val)
                {
                    // 以 slow 后的第三个结点和 p2 指向的结点开始循环向两边比较
                    slow = slow->next->next;
                    while(slow)
                    {
                        if (slow->val != p2->val)
                        {
                            return false;
                        }
                        else
                        {
                            slow = slow->next;
                            p2 = p2->next;
                        }
                    }
                    return true;
                }
                else
                {
                    return false;
                }
            }
            // 奇数结点
            else
            {
                // 以 slow 后的第一个结点和 p2 指向的结点开始循环向两边比较
                slow = slow->next;
                while(slow)
                {
                    if (slow->val != p2->val)
                    {
                        return false;
                    }
                    else
                    {
                        slow = slow->next;
                        p2 = p2->next;
                    }
                }
                return true;
            }
        }
                
    }
};

获取更多精彩,请关注「seniusen」!


seniusen

相关文章

  • 234. 回文链表

    234. 回文链表[https://leetcode.cn/problems/palindrome-linked-...

  • LeetCodeEmm

    234. 回文链表[https://leetcode-cn.com/problems/palindrome-lin...

  • 234. 回文链表

    234. 回文链表[https://leetcode-cn.com/problems/palindrome-lin...

  • Leetcode 234 回文链表

    234. 回文链表[https://leetcode-cn.com/problems/palindrome-lin...

  • 链表 Leetcode 234 回文链表

    题目 请判断一个链表是否为回文链表。 示例 1: 输入: 1->2输出: false示例 2: 输入: 1->2-...

  • LeetCode 234——回文链表

    1. 题目 请判断一个链表是否为回文链表。 示例 1:输入: 1->2输出: false示例 2: 输入: 1->...

  • 如何判断回文链表

    读完本文,你可以去力扣拿下如下题目: 234.回文链表[https://leetcode-cn.com/probl...

  • LeetCode|234.回文链表

    题目描述 等级: 简单请判断一个链表是否为回文链表。 示例 1: 示例 2: 进阶:你能否用 O(n) 时间复杂度...

  • LeetCode 234. 回文链表

    234. 回文链表 请判断一个链表是否为回文链表。 示例 1: 输入: 1->2输出: false 示例 2: 输...

  • leetCode.234 - 回文链表

    题目 请判断一个链表是否为回文链表。示例 1: 示例 2: 进阶:你能否用 O(n) 时间复杂度和 O(1) 空间...

网友评论

    本文标题:LeetCode 234——回文链表

    本文链接:https://www.haomeiwen.com/subject/hrcaaftx.html