LeetCode19题疑问:操作answer链表后为何可返回原head?
LeetCode 19题:删除链表倒数第N个结点 疑问解答
代码示例
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode countList = head; int length = 0; // get the length of list while(countList != null){ length++; countList = countList.next; } // if it is first node from beginning just return next nodes if(length == n){ return head.next; } // get the stop point int stop = length - n - 1; ListNode answer = head; for(int i = 0; i < stop; i++){ answer = answer.next; } // removing the node answer.next = answer.next.next; return head; } }
疑问描述
我正在解决LeetCode第19题《删除链表的倒数第N个结点》,存在如下疑问:在对answer链表进行操作后,为何能返回原head?操作answer链表的过程中,原head指向的链表是否被修改?我原本认为ListNode answer = head;只是复制head链表,操作answer不会影响head。
解答
核心原因是Java中对象变量存储的是引用地址,不是对象本身,这里的ListNode answer = head;根本没有复制链表,只是让answer和head指向内存中同一个链表的头节点——它们是同一个链表的两个"指针"而已。
具体拆解:
- 执行
ListNode answer = head;时,answer和head指向的是同一个链表对象,没有任何复制行为,只是多了一个指向它的引用。 - 后续
answer = answer.next;的操作,只是把answer这个引用移动到链表的下一个节点,head依然指向原链表的头节点,整个链表的结构始终是同一个,没有被复制。 - 关键操作
answer.next = answer.next.next;:此时answer指向原链表中的某个节点(要删除节点的前一个节点),修改这个节点的next属性,直接改变了原链表的结构——因为这个节点本身就是原链表的一部分。 - 最后返回
head,是因为head依然指向修改后的链表的头节点(只有当要删除的是头节点时,代码才会直接返回head.next,这种情况已经单独处理)。
举个实际例子:假设原链表是1->2->3->4->5,n=2(要删除倒数第2个节点4)。计算后stop=5-2-1=2,answer从head出发移动2次,指向节点3,然后把3.next改成5,原链表就变成1->2->3->5,head依然指向1,所以返回head就是修改后的完整链表。
内容的提问来源于stack exchange,提问作者dhhhhhhh
相关产品推荐
相关产品推荐

