一、203.移除鏈表元素
題目:203. 移除鏈表元素 - 力扣(LeetCode)
視頻:手把手帶你學會操作鏈表 | LeetCode:203.移除鏈表元素_嗶哩嗶哩_bilibili
講解:代碼隨想錄
注意:
針對頭結點和非頭結點的刪除方式是不一樣的:
正常節點:要找到該節點的上一節點
頭結點:直接把 head 往后移一位
所以就要進行判斷,要刪除的節點是不是頭結點(方法一)
或者,在頭結點前設立一個虛擬節點(dummy head)(方法二)
方法一:判斷鏈表刪除元素
class Solution {public ListNode removeElements(ListNode head, int val) {while (head != null && head.val == val) {head = head.next;}ListNode curr = head;while (curr != null && curr.next != null) { if (curr.next.val == val) {curr.next = curr.next.next;} else {curr = curr.next;}}return head;}
}
要點 1:
判斷頭結點是否符合的時候,使用 if 就只能判斷一次,如果第二個元素也符合條件,就漏刪了
所以要用 while ,在頭結點不符合條件的時候,才繼續往下走
要點 2:
往后查找的時候,要定義一個指針,那么指針的位置指向哪里?
如果是第二位,第二位符合刪除條件,找不到上一位的 next 指針。(x)
所以要指向頭結點
嘗試過程:
class Solution {public ListNode removeElements(ListNode head, int val) {while (head != null && head.val == val) {head = head.next;}ListNode curr = head;while (curr.next != null && curr != null) { //這里有問題!!if (curr.next.val == val) {curr.next = curr.next.next;} else {curr = curr.next;}}return head;}
}
報這個錯誤的原因:
雖然從邏輯上看是想同時確保當前節點 curr
和它的下一個節點 curr.next
都不為 null
,但如果 curr
本身已經是 null
了,再去訪問 curr.next
就會直接拋出空指針異常。
正確的做法應該是先判斷 curr
是否為 null
,再去判斷 curr.next
是否為 null
,像這樣修改條件為 while (curr!= null && curr.next!= null)
。
方法二:設置虛擬頭結點
class Solution {public ListNode removeElements(ListNode head, int val) {ListNode dummy = new ListNode();dummy.next = head;ListNode curr = dummy;while(curr != null && curr.next != null){if(curr.next.val == val){curr.next = curr.next.next;} else {curr = curr.next;}}return dummy.next;}
}
注意頭結點的指針是不能更改的,因為最后要用到頭結點返回。
二、707.設計鏈表
題目:707. 設計鏈表 - 力扣(LeetCode)
視頻:幫你把鏈表操作學個通透!LeetCode:707.設計鏈表_嗶哩嗶哩_bilibili
講解:代碼隨想錄
利用虛擬頭結點方式,對所有結點統一操作。
class MyLinkedList {class ListNode {int val;ListNode next;ListNode(int val) {this.val = val;}}private int size;private ListNode head;// 初始化public MyLinkedList() {this.size = 0;this.head = new ListNode(0);}public int get(int index) {if (index < 0 || index >= size) {return -1;}ListNode cur = head;for (int i = 0; i <= index; i++) {cur = cur.next;}return cur.val;}public void addAtHead(int val) {ListNode newNode = new ListNode(val);newNode.next = head.next;head.next = newNode;size++;}public void addAtTail(int val) {ListNode newNode = new ListNode(val);ListNode cur = head;while (cur.next != null) {cur = cur.next;}cur.next = newNode;size++;}public void addAtIndex(int index, int val) {if (index < 0 || index >= size) {return;}ListNode cur = head;for (int i = 0; i < index; i++) {cur = cur.next;}ListNode newNode = new ListNode(val);newNode.next = cur.next;cur.next = newNode;size++;}public void deleteAtIndex(int index) {if(index < 0 || index >=size){return;}ListNode cur = head;for(int i=0; i<index; i++){cur = cur.next;}cur.next = cur.next.next;size--;}
}
三、206.反轉鏈表
題目:
視頻:
講解: