博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LeetCode 234——回文链表
阅读量:7267 次
发布时间:2019-06-29

本文共 2861 字,大约阅读时间需要 9 分钟。

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

转载地址:http://jxfcm.baihongyu.com/

你可能感兴趣的文章
深入学习之mysql(三)单表操作
查看>>
web请求
查看>>
正则基础之——贪婪与非贪婪模式
查看>>
数据结构【基础知识点总结】
查看>>
Android Studio中getter和setter模版配置
查看>>
hdu 4655 Cut Pieces(想法题)
查看>>
傅里叶变化性质
查看>>
Multi Crystal Reports printing - Code
查看>>
简化得最没道理的6个汉字,让人大跌眼镜
查看>>
以太网帧、TCP与UDP段以及IP数据报格式总结
查看>>
Mongodb3安装授权
查看>>
22-angular.module
查看>>
emacs初步学习
查看>>
“Unable to load DLL” problem with SQL Server CE
查看>>
【分层图】分层图学习笔记
查看>>
jQueryUI日期显示
查看>>
转:ASCII 与 字符集存储的一篇文章
查看>>
RMAN-FORMAT-CONFIGURE及动态性能表
查看>>
设计模式(1)-行为类
查看>>
【HTK]htk阶级学习
查看>>