LeetCode:234. 回文链表

一、问题描述

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

示例 1:

输入: 1->2
输出: false

示例 2:

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

二、解题思路

将链表分为两段,并且把后面一段进行倒置,然后再比较前后两段是否相同即可。最简单的方法就是先计算链表的长度,然后将前面一半用头插法的办法进行倒置,最后再比较,但是由于需要的是一半这个特殊的位置,所以我们可以考虑快慢指针,何谓快慢指针,其实就是两个指针,一根指针一次移动一个位置,另一个指针一次移动两个位置。快慢指针适合用于有中点相关的场景(有中点或倍数的时候可以考虑快慢指针来解决问题)

三、代码实现

/**
 * 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 || !head->next) return true;    
       
        ListNode *slow = head, *fast = head;
        while (fast && fast->next) //快慢指针法,让slow指向链表中部位置
        {
            slow = slow->next;
            fast = fast->next->next;
        }
        //退出时,fast为最后一个结点或者null,slow处在中间位置
        //与结点数有关,左子链表head~slow-1, 右子链表为slow~end
        //右子链表比左子链表长一或者相等)
        //例:0~10,slow 5, fast 10; 0~9,slow5,fast null (0表示头结点,slow和fast的起点)
       
        ListNode* right = reverseList(slow);//反转右边链表
        ListNode* left = head;
       
        while(left && right)//比较左右子链表是否相等
        {
            if(left->val == right->val)
            {
                left = left->next;
                right = right->next;
            }
            else
                return false;
           
        }
        return true;
    }
private:
    ListNode* reverseList(ListNode* head) {
        //pre永远指向null,相当于一个尾节点
        ListNode* pre = NULL;
        ListNode* cur = head;
        while(cur != NULL){
            //next用来保存下一个节点。因为会把当前节点cur拿下来,赋值给pre
            ListNode* next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章