例如LeetCode83删除链表中的重复元素
错误解法:
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head==null ||head.next==null) return head;
while(head.next!=null){
if(head.val!=head.next.val){
head=head.next;
}
else{
head.next=head.next.next;
}
}
return head;
}
}
头节点一直在动,无法取到头节点的值
比如我们有一个链表如下:
此时 head 就是 1 这个位置,但是链表是连着的,输出 head 你会得到一整串以 1 为起点的链子,也就是[1, 2, 3],head.next 会输出 [2, 3]
因此,我们正确做法可以找一个跑腿指针去操作链表,这样head头节点就不会移动了
class Solution {
public ListNode deleteDuplicates(ListNode head) {
//理解值传递和引用传递
if (head == null) {
return head;
}
ListNode cur = head;
while (cur.next != null) {
if (cur.val == cur.next.val) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
return head;
}
}
【编程】为什么不能直接对链表头head进行操作?_YaoYee_7的博客-CSDN博客_链表中head
对于网上对于为什么不能直接操作头节点的最佳回答:
首先,由于单链表只能从前往后遍历,不能回头,所以一定需要保存第一个节点才能访问完整的链表。也就是:必须在每个时刻都有一个指针是指向第一个节点的。既然目前head已经指向了它,那就不操作head,让head一直指向第一个节点好了。所以需要新建指针,来对链表进行操作。对链表的大部分操作都是这样处理的,不会动head指针。
其次,对于“删除链表”这个操作,假定删除的是current,那么需要把current的前一个节点的next指向current的后一个节点,然后释放current对应的内存。还是由于单链表不能回头,既然要访问current的前一个节点,就必须用一个指针指向current的前一个节点,在这里用previous表示这个指针了。再加上current本身也要保存(不然没办法释放current占用的内存),就至少需要两个指针了。
对链表的所有操作都画个图看比较明了~