You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链表回文判断C语言代码输入1,2,1,1时失效的错误排查

问题描述

现有C语言实现的链表回文判断功能,多数测试用例运行正常,但输入节点序列为1、2、1、1时会返回错误判断结果。

相关代码

  • 反转链表函数前置声明 + 链表节点计数函数
ListNode *reverseLL(ListNode*);
int nodeCounter(struct ListNode* head){
    struct ListNode* ptr=head;
    int counter=0;
    while(ptr!=NULL){
        counter++;
        printf("%d ",ptr->val);
        ptr=ptr->next;
    }
    return counter;
}
  • 回文判断主逻辑
bool isPalindrome(struct ListNode* head){
    struct ListNode *revhead=reverseLL(head);
    int length=nodeCounter(head),mid=length/2,count=0;
    struct ListNode *ptr=head;
    struct ListNode *ptr1=revhead;
    while(length!=mid){
        printf("\n %d == %d",ptr->val,ptr1->val);
        if(ptr->val!=ptr1->val){
            printf("in");
            return 0;
        }
        ptr=ptr->next;
        ptr1=ptr1->next;
        length--;       
    }
    return true;
}
错误根因定位

核心问题出在对原链表做原地全反转后,仍用原头节点指针遍历原链表:

  1. 代码中调用的reverseLL是原地反转实现,执行时会直接修改原链表所有节点的next指针指向,反转完成后,传入的原head指针不再是原链表的头节点,而是反转后链表的尾节点,其next指针最终会指向NULL。
  2. 代码执行顺序存在逻辑漏洞:先执行全链表反转,再调用nodeCounter(head)统计长度。此时从原head(反转后的尾节点)出发遍历,根本无法遍历到所有节点,统计出的长度完全错误。

以输入1->2->1->1为例复现错误流程:

  • 反转前链表结构:节点A(1) -> 节点B(2) -> 节点C(1) -> 节点D(1) -> NULL,原head指向节点A
  • 原地反转后链表结构:节点D(1) -> 节点C(1) -> 节点B(2) -> 节点A(1) -> NULL,revhead指向D,原head仍指向A,而A的next已经被修改为NULL
  • 调用nodeCounter(head)时从A出发遍历,仅能统计到1个节点,计算得到length=1、mid=0
  • 循环仅执行1次:比对A的值1和D的值1,判定相等后length减为0,直接退出循环返回true,完全没检测到后续节点值不匹配的问题,最终判断错误。
修复方向
  • 不要直接对整个原链表做原地全反转后再遍历原头指针,这种写法会彻底破坏原链表结构,导致遍历逻辑完全失效。
  • 常规O(1)空间的正确实现逻辑:
    • 先遍历原链表统计总长度,定位到链表中间节点
    • 仅原地反转链表的后半段,不修改前半段的指针指向
    • 用两个指针分别从原链表头、后半段反转后的新头出发,逐节点比对值,全部匹配则为回文
    • 比对完成后可再次反转后半段,恢复原链表结构
  • 如果不需要严格限制空间复杂度,更简单的写法是先遍历链表把所有节点值存入顺序数组,再用双指针从数组头尾向中间逐位比对,代码逻辑更简单,不容易出现指针操作错误。

内容的提问来源于stack exchange,提问作者flanker99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 06:09:10