合并两个ListNode时循环问题解析:两种初始化方式的差异
问题解惑:两种ListNode初始化方式的差异与循环错误原因
一、两种写法的本质差异
- 第一种写法
sol = ListNode:你只是把ListNode类本身赋值给了变量sol,并没有创建ListNode的实例对象。后续给sol.val和sol.next赋值,本质是修改了ListNode这个类的类属性(所有该类的实例都会共享的属性),而不是某个独立节点的属性。 - 第二种写法
sol = ListNode(val=l1.val):这是调用ListNode的构造函数,创建了一个全新的ListNode实例对象,sol指向这个独立的实例。后续的sol.val和sol.next都是这个实例独有的属性,和ListNode类本身以及其他实例完全无关。
二、为什么第一种写法会产生循环错误
递归合并链表的过程中,每次调用mergeTwoLists时,你都在修改同一个ListNode类的val和next属性:
- 第一次递归时,你把ListNode类的
val设为当前l1的val,next设为下一次递归的返回值。 - 下一次递归调用时,又会覆盖ListNode类的
val和next属性,把它们改成当前递归层的对应值。 - 最终所有递归返回的都是同一个ListNode类对象,而不是不同的节点实例。当递归回溯时,类的
next属性会被不断覆盖,最终形成类对象自身引用自身的循环(比如某个递归层把next设回了这个类本身),导致链表出现循环结构。
而第二种写法每次都创建独立的实例,每个节点的next指向的是另一个独立的实例,不会出现类属性被共享覆盖的问题,自然能正常构建出有序链表。
内容的提问来源于stack exchange,提问作者kks
相关产品推荐
相关产品推荐

