LeetCode 234——回文链表

1. 题目

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

示例 1:

输入: 1->2

输出: false

示例 2:

输入: 1->2->2->1

输出: true

进阶:

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

2. 思路

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

  • 偶数结点情况如下

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

  • 奇数个结点时,我们依然可以分别得到以 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」!

原文地址:https://www.cnblogs.com/seniusen/p/9784343.html

时间: 2024-08-07 05:15:53

LeetCode 234——回文链表的相关文章

Leetcode 234. 回文链表(进阶)

题目描述: 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 解法一:(空间复杂度O(n)) 遍历一遍链表压栈,借助栈把链表倒序,然后依次比较"原链表元素"和"新栈中元素",如果都相等则返回true,否则返回false. 这样简单粗暴,代码的主体包含在解法二中了,这里不列出了.

Leetcode 234. 回文链表

bool isPalindrome(ListNode* head) { ListNode* fast = head; ListNode* slow = head; //如果没有元素 if(head==NULL) return true; //如果就一个元素 if(fast->next==NULL) return true; //如果就两个元素 if(fast->next->next==NULL) return fast->val == fast->next->val;

领扣(LeetCode)回文链表 个人题解

请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 一个最暴力的做法,遍历一次,内容保存在数组内,然后判断是否回文. 遇到一个比较严重的问题需要记录一下,使用Vector类时,设定的类型为Integer,必须使用Equals函数来判断两数是否相等,使用==则不行.奇怪的是,只有部分判断是错误的. 查阅百度,发现了问题所在:

234. 回文链表

请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 1 import java.util.ArrayList; 2 3 public class PalindromeLinkedList { 4 static class ListNode { 5 int val; 6 ListNode next; 7 ListNode(int x) { 8 val = x; 9 } 10 } 11 12 //

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 and O(1) space? 判断一个链表是否为回文串 思路:1.找到中间点,2.反转后半部分链表,3.判断前半部分与后半部分是否相同 /** * Definition for singly-linked list. * public class ListNode { * public int v

【Leetcode链表】回文链表(234)

题目 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 解答 两种方法: 遍历链表,用数组存值,再比较.时间复杂度O(n),空间复杂度O(n) 指针法:找到中点,反转中点之后的链表,再比较.时间复杂度O(n),空间复杂度O(1) 通过代码如下: # Definition for singly-linked list.

【leetcode 简单】 第六十七题 回文链表

请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def r

如何判断一个单向链表是否为回文链表(Palindrome Linked List)

题目:给定一个单向链表,判断它是不是回文链表(即从前往后读和从后往前读是一样的).原题见下图,还要求了O(n)的时间复杂度O(1)的空间复杂度. 我的思考: 1,一看到这个题目,大脑马上想到的解决方案就是数组.遍历链表,用数组把数据存下来,然后再进行一次遍历,同时用数组反向地与之比较,这样就可以判断是否回文.这个方法时间复杂度是O(n),达到了要求,然而空间复杂度显然不满足要求.所以,开数组这一类的方法显然不是最佳的. 2,既然要满足O(1)的空间复杂度,我就想到了用一个变量来存储这些数据,恰好

[CareerCup] 2.7 Palindrome Linked List 回文链表

2.7 Implement a function to check if a linked list is a palindrome. LeetCode上的原题,参见我之前的博客Palindrome Linked List 回文链表.