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

单链表最大重复元素序列删除逻辑失效,执行异常求助

问题解决:单链表删除最长重复序列的BUG修复

你的代码核心逻辑方向没问题,但在指针处理、边界判断和状态变量管理上出了漏洞,导致程序卡住、报错或删除逻辑失效。下面梳理问题,给出修复后的代码和关键说明。

原代码的核心问题

  1. 非法访问None属性:第一个while循环中,当pointer是最后一个节点时,pointer.next为None,此时执行pointer.next.elem直接触发报错,这也是你之前遇到崩溃的原因。
  2. 状态变量逻辑混乱:变量a的切换时机完全错误,导致序列的起始/结束位置记录彻底混乱,最后一个元素无法被正常处理,后续删除逻辑也找不到正确的前驱和后继节点。
  3. 依赖位置计数易出错:用count、first、last这类位置变量跟踪序列,远不如直接用指针跟踪节点准确,很容易因为计数偏差导致误删整个链表或删不掉目标序列。
  4. 删除阶段指针越界:后续for循环中,当pointer2遍历到链表尾部时,pointer2.next为None,访问pointer2.next.elem会再次报错,且无法正确定位first_after_sequence。

修复后的代码

from slistH import SList
from slistH import SNode


class SList2(SList):
    def delLargestSeq(self):
        # 空链表或只有一个节点,无需处理直接返回
        if self._head is None or self._head.next is None:
            return

        # 初始化变量:跟踪最长重复序列的前驱、结束节点,以及当前序列长度
        max_seq_len = 1
        current_seq_len = 1
        prev_node = self._head
        current_node = self._head.next
        
        # 记录最长序列的关键节点:前驱节点、结束节点
        max_prev_node = None
        max_end_node = self._head

        while current_node is not None:
            if current_node.elem == prev_node.elem:
                current_seq_len += 1
                # 当前序列长度超过已记录的最长序列时,更新最长序列信息
                if current_seq_len > max_seq_len:
                    max_seq_len = current_seq_len
                    # 找到当前序列的前驱节点
                    temp = self._head
                    max_prev_node = None
                    while temp != prev_node and temp is not None:
                        max_prev_node = temp
                        temp = temp.next
                    max_end_node = current_node
            else:
                # 当前序列结束,比较长度是否更新最长序列
                if current_seq_len > max_seq_len:
                    max_seq_len = current_seq_len
                    temp = self._head
                    max_prev_node = None
                    while temp != prev_node and temp is not None:
                        max_prev_node = temp
                        temp = temp.next
                    max_end_node = prev_node
                # 重置当前序列长度
                current_seq_len = 1
            
            # 移动指针继续遍历
            prev_node = current_node
            current_node = current_node.next

        # 处理最后一段未比较的序列
        if current_seq_len > max_seq_len:
            max_seq_len = current_seq_len
            temp = self._head
            max_prev_node = None
            while temp != prev_node and temp is not None:
                max_prev_node = temp
                temp = temp.next
            max_end_node = prev_node

        # 执行删除操作
        if max_prev_node is None:
            # 最长序列在链表头部,直接修改head指向序列后的第一个节点
            self._head = max_end_node.next
        else:
            # 前驱节点的next指向最长序列后的第一个节点
            max_prev_node.next = max_end_node.next


# 测试代码
nodes_list = SList2()
for i in (1, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6):
    nodes_list.addLast(i)

print(nodes_list)
nodes_list.delLargestSeq()
print(f"{nodes_list} || final list")

关键修复说明

  1. 提前处理边界情况:先判断空链表或只有一个节点的场景,直接返回避免后续逻辑出错。
  2. 用指针直接跟踪序列:放弃位置计数,改用prev_node和current_node跟踪当前序列,同时记录最长序列的max_prev_node(前驱节点)和max_end_node(结束节点),删除时只需修改指针指向即可,逻辑更可靠。
  3. 避免非法访问:所有访问节点next或elem的操作,都确保当前节点不为None。
  4. 补全最后序列的判断:遍历结束后单独处理最后一段序列的长度比较,避免漏掉最后一段重复序列。
  5. 正确处理头部序列:如果最长序列在链表头部,直接修改self._head指向序列后的节点,无需额外找前驱。

测试你的输入链表[1,3,3,3,3,4,4,5,5,5,6,6],最长重复序列是4个3,删除后链表会变成[1,4,4,5,5,5,6,6],程序可以正常结束,不会出现卡住、报错或删除错误的情况。

内容的提问来源于stack exchange,提问作者Raúl Armas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:55:02