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)

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

相关推荐
GreenTea3 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
码匠许师傅3 小时前
【C++ 面试真题】聊聊 C++ 的移动语义与右值引用
java·c++·面试
fqq34 小时前
力扣刷题前置Java语法
算法·leetcode·职场和发展
小小龙学IT5 小时前
DuckDB 深度实战:用 C++ 在进程内跑一个「分析型数据库」
数据库·c++
知无不研6 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
半夏微凉半夏殇6 小时前
x11与weston对比,优先选哪个
leetcode·均值算法·eclipse
2501_906565126 小时前
数学之美探究
算法
oier_Asad.Chen7 小时前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环
C++ 老炮儿的技术栈8 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
leisoo80978 小时前
财报数据怎么排雷本地化Python构建财务异常预警系统
人工智能·python·算法