双指针法移除有序链表重复元素异常,求代码问题分析
LeetCode 83题双指针解法错误分析
我正在解决LeetCode的83. 删除排序链表中的重复元素问题,题目要求如下:
给定一个有序链表的
head节点,删除所有重复元素,使每个元素只出现一次。返回同样保持有序的链表。约束条件
- 链表中的节点数范围为
[0, 300]。- -100 <= Node.val <= 100
- 链表保证按升序排列。
我尝试用双指针解法,但代码无法正常运行/得到异常结果。我不想直接要正确代码,只想搞懂自己写的代码错在哪里,以及实际执行过程中发生了什么。
我的代码如下:
class Solution: def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: if not head: return None #: Intutive O(n) single pointer:# # curr = head # while curr.next: # if curr.val == curr.next.val: # curr.next = curr.next.next # else: curr = curr.next # return head #. T.C = O(n), S.C: O(1) #. Uses only one temp value #. Goes through each variable and skips the node with same value. #+ we can improve this as we could try to skip multiple duplicate nodes at once #: Two pointer :# slow, fast = head , head.next while fast != None: if slow == fast: fast=fast.next slow.next = fast else: fast = fast.next slow = slow.next slow.next = None return head
核心错误点
- 重复判断逻辑完全错误:你用
slow == fast比较的是指针本身的地址(是否指向同一个节点),而不是节点的val值是否相等。但初始时slow和fast就指向不同节点,这个条件永远不会触发,处理重复的代码根本没执行过。 - 指针同步移动无意义:因为上面的条件永远不满足,每次循环都会执行else分支,让
fast和slow同步往后走,完全没有跳过任何重复节点。 - 末尾截断操作无必要但不影响结果:循环结束时
slow已经在链表最后一个节点,slow.next原本就是None,这步操作不会改变链表,但前面的错误已经导致重复元素完全没被处理。
实际执行过程举例(以输入1 -> 1 -> 2为例)
- 初始状态:
slow指向第一个1,fast指向第二个1。 - 第一次循环:
slow == fast为False,执行else分支,fast移动到2,slow移动到第二个1。 - 第二次循环:
fast不为None,slow == fast仍为False,执行else分支,fast移动到None,slow移动到2。 - 循环结束,设置
slow.next = None(无变化),返回原链表,结果还是1 -> 1 -> 2,重复元素未被删除。
内容的提问来源于stack exchange,提问作者Prodaturu
相关产品推荐
相关产品推荐

