LeetCode热题100——234.回文链表(两种解法)

题目

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false

示例 1:

输入: head = 1,2,2,1
**输出:**true

示例 2:

输入: head = 1,2
**输出:**false

法一(数组辅助+双指针):

题解

将链表中的数值复制到一个数组中,然后使用双指针从两端向中间比较即可

答案

cpp 复制代码
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> nums;
        while(head!=NULL){
            nums.push_back(head->val);
            head=head->next;
        }
        int i=0,j=nums.size()-1;
        while(i<j){
            if(nums[i]==nums[j]){
                i++;
                j--;
            }
            else {
                return false;
            }
        }
        return true;
    }
};

复杂度分析

  • 时间复杂度 :O(n)

    遍历链表一次 O(n),双指针遍历数组一次 O(n/2) ≈ O(n)。

  • 空间复杂度 :O(n)

    使用一个与链表长度相同的数组存储所有节点的值。

法二(快慢指针找中点+反转后半段链表):

题解

1.使用快慢指针找到链表的中间节点(前半部分的尾节点)。

  • 定义快指针 fast 和慢指针 slow,都指向 head。
  • 当 fast->next 和 fast->next->next 均不为空时,fast 每次移动两步,slow 每次移动一步。
  • 循环结束时,slow 指向的就是前半部分的尾节点。

2.反转链表的后半部分(详见如下解析:题目LeetCode热题100------206.反转链表)

https://blog.csdn.net/wyhwyh___/article/details/160566554?spm=1001.2014.3001.5501https://blog.csdn.net/wyhwyh___/article/details/160566554?spm=1001.2014.3001.5501

3.同时遍历前半部分和反转后的后半部分,比较对应节点的值是否相等。

4.恢复链表原状。

答案

cpp 复制代码
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode* firstHalfEnd = endOfFirstHalf(head);
        ListNode* secondHalfStart = reverseList(firstHalfEnd->next);

        ListNode* p1=head;
        ListNode* p2=secondHalfStart;
        while(p2!=NULL){
            if(p1->val!=p2->val) return false;
            p1=p1->next;
            p2=p2->next;
        }
        //恢复链表
        firstHalfEnd->next=reverseList(secondHalfStart);
        return true;
    }

    //快慢指针找前半部分的尾节点
    ListNode* endOfFirstHalf(ListNode* head){
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast->next!=NULL&&fast->next->next!=NULL){
            fast=fast->next->next;
            slow=slow->next;
        }
        return slow;
    }

    //反转链表,返回后半部分的新头节点
    ListNode*reverseList(ListNode* head){
        ListNode* pre=NULL;
        ListNode* cur=head;
        while(cur!=NULL){
            ListNode* nextTemp=cur->next;
            cur->next=pre;
            pre=cur;
            cur=nextTemp;
        }
        return pre;
    }
    
};

复杂度分析

  • 时间复杂度 :O(n)

    找中点 O(n),反转链表 O(n),比较 O(n),整体 O(n)。

  • 空间复杂度 :O(1)

    只使用了若干个指针变量,没有使用额外的数组或递归栈。

相关推荐
To_OC4 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
2401_841495644 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
fqbqrr4 小时前
2607C++,soui与安卓
c++·soui
fqbqrr8 小时前
2607C++,使用微软detours勾挂工具
c++
爱刷碗的苏泓舒8 小时前
PPP-AR 中的参考星选取:数学原理、评价指标与切换处理
算法·gnss·模糊度固定·ppp-ar·星间单差·参考星·卫星端偏差
蓝悦无人机11 小时前
C++基础 — 函数总结
开发语言·c++
烬羽11 小时前
递归老写崩?一个"退回"公式,把回溯题变成填空题
javascript·深度学习·算法
闪电悠米11 小时前
力扣hot100-41.缺失的第一个正数-原地哈希详解
数据结构·算法·哈希算法
星空露珠12 小时前
28种颜色对应名称,
开发语言·数据库·算法·游戏·lua