Leetcode 234. 回文链表

原题链接:Leetcode 234. 回文链表

解法一:转换为数组

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> val;
        while(head!=nullptr){
            val.push_back(head->val);
            head=head->next;
        }
        int l=0,r=val.size()-1;
        while(l<r){
            if(val[l]!=val[r]){
                return false;
            }
            l++;
            r--;
        }
        return true;
    }
};

解法二:

  1. 找到前半部分链表的尾节点。
  2. 反转后半部分链表。
  3. 判断是否回文。
cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    // 876. 链表的中间结点
    ListNode * middleNode(ListNode* head) {
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast!=nullptr && fast->next!=nullptr){
            fast=fast->next->next;
            slow=slow->next;
        }
        return slow;
    }
    // 206. 反转链表
    ListNode * reverseList(ListNode* head) {
        ListNode* pre=nullptr;
        ListNode* now=head;
        while(now!=nullptr){
            ListNode* tmp=now->next;
            now->next=pre;
            pre=now;
            now=tmp;
        }
        return pre;
    }
    bool isPalindrome(ListNode* head) {
        ListNode*  middle = middleNode(head);
        ListNode*  head2 = reverseList(middle);
        while(head2){
            if(head->val!=head2->val) return false;
            head=head->next;
            head2=head2->next;
        }
        return true;
    }
};

问:为什么不能反转整个链表,然后判断?

答: 代码中用的反转链表的做法是题目206. 反转链表的做法,是在原地修改链表的,而不是"复制后修改",也就是反转链表的操作会影响原来的链表,返回的头节点是原链表的尾节点

ListNode* copy = head;

ListNode* reversedCopy = reverseList(copy);
这样的做法是不行的,因为 ListNode* copy = head; 并没有真正复制链表,只是让 copy 指针和 head 指针指向同一个链表(内存地址相同)。此时对 copy 进行反转操作,本质上还是在修改原链表的节点,和直接反转 head 没有区别。(ListNode* copy = head; 是指针赋值,不是链表复制,copy 和 head 指向的是同一片内存(同一个链表节点序列)。)
举例说明: 原链表:1 -> 2 -> 3 -> null 执行 ListNode* copy = head; 后,copy 和 head

都指向 1。 反转 copy 后,链表变成 1 <- 2 <- 3(copy 现在指向 3),但原链表的 head 仍然指向 1,而

1->next 已经变成 null------ 原链表被破坏了。

要真正避免影响原链表,必须为每个节点创建新的副本(用 new ListNode(...)),而不是简单地复制指针。如:

cpp 复制代码
	//复制链表(创建新节点,不影响原链表)
    ListNode* copyList(ListNode* head) {
        if (head == nullptr) return nullptr;
        // 创建虚拟头节点简化复制
        ListNode* dummy = new ListNode(0);
        ListNode* curr = dummy;
        while (head != nullptr) {
            // 为每个节点创建副本
            curr->next = new ListNode(head->val);
            curr = curr->next;
            head = head->next;
        }
        return dummy->next;
    }
相关推荐
GuWenyue30 分钟前
传统Agent工具两大痛点!300行代码落地MCP跨语言工具,彻底解耦LLM与工具
前端·人工智能·算法
我叫洋洋2 小时前
C ++ [ hello world ]
c语言·c++·算法
奋发向前wcx3 小时前
y1,y2总复习笔记5 2026.7.19
数据结构·笔记·算法
战族狼魂6 小时前
高频面试题精选:分治与AI Agent架构
人工智能·算法·大模型·大语言模型
李剑一6 小时前
你用过网易的将军令嘛?它底层实现账号保护的原理相当简单粗暴
算法
Scott9999HH6 小时前
告别流量波动玄学!从法拉第电磁定律到底层 C/C++ 流量累积算法,深度解密工业级电磁流量计选型与开发
c语言·c++·算法
中达瑞和-高光谱·多光谱7 小时前
1nm到8nm光谱分辨率,你的应用该选哪款光谱相机?
算法·高光谱·高光谱相机
香辣牛肉饭8 小时前
【算法】动态规划 最长公共子序列(LCS)
经验分享·笔记·算法·动态规划
旖-旎8 小时前
LeetCode 279:完全平方数(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题