【LeetCode-链表】回文链表

题目描述

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

输入: 1->2
输出: false

输入: 1->2
输出: false

题目链接:https://leetcode-cn.com/problems/palindrome-linked-list/

思路1

回文链表就是正向遍历序列和反向遍历序列一样的链表,所以可以遍历链表一边,用队列记录链表的正向遍历序列,用栈记录反向遍历序列,然后比较即可。下面的代码没有用队列,用的是vector,其实是一样的。代码如下:

/**
 * 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==nullptr){
            return true;
        }

        vector<int> v;  // 记录正向遍历序列
        stack<int> s;   // 记录反向遍历序列
        while(head!=nullptr){
            v.push_back(head->val);
            s.push(head->val);
            head = head->next;
        }

        for(int i=0; i<v.size(); i++){
            int st = s.top();
            s.pop();
            if(v[i]!=st){
                return false;
            }
        }
        return true;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度: O(n)
    用到了vector和栈,辅助空间随着链表的增长而线性增长。

思路2

先将链表分为两部分,然后将第二部分(后一部分)翻转后与第一部分比较。
将链表分为两部分可以先求链表长度n,然后找第n/2个节点。因为链表的长度可能为偶数和奇数,这两种情况下的分割是不一样的。当链表长度为偶数时,两条链表长度相等;当长度为奇数时,第一条链表的长度比第二条链表的长度大一,所以要翻转第二条链表并根据第二条链表比较。代码如下:

/**
 * 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==nullptr || head->next==nullptr){
            return true;
        }

        /*分割链表*/
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast->next!=nullptr && fast->next->next!=nullptr){
            fast = fast->next->next;
            slow = slow->next;
        }
        ListNode* head1 = head;
        ListNode* head2 = slow->next;
        slow->next = nullptr;
        
        /*翻转后一个链表*/
        ListNode* curNode = head2;
        ListNode* preNode = nullptr;
        ListNode* nextNode = nullptr;
        while(curNode!=nullptr){
            nextNode = curNode->next;
            curNode->next = preNode;
            preNode = curNode;
            curNode = nextNode;
        }
        head2 = preNode;
        
        while(head2!=nullptr){  // 注意要使用第2个链表,因为第2个链表长度小于等于第1个链表长度
            if(head1->val != head2->val){
                return false;
            }
            head1 = head1->next;
            head2 = head2->next;
        }
        return true;
    }
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

猜你喜欢

转载自www.cnblogs.com/flix/p/12673432.html