文章目錄
(一)練習01:刪除節點
(二)練習02:反轉鏈表(遞歸)
(三)練習03:反轉鏈表(迭代)(頭插法)
(四)練習04:環形鏈表
(五)作業題
(一)練習01:刪除節點
https://leetcode-cn.com/problems/delete-node-in-a-linked-list/
我們的目標是刪除指定的node,但是卻不提供查詢前一個node的方法
我們可以換一種思路,把後一個節點的值,覆蓋掉要刪除的節點的值(用next可以獲取下一個節點)
然後把值爲9的節點的next指向next的next,如下:
代碼如下:
/**
* 刪除指定的節點
*
* @param node
*/
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
(二)練習02:反轉鏈表(遞歸)
https://leetcode-cn.com/problems/reverse-linked-list/
傳入head對應的鏈表如下:
期望的結果如下:
遞歸的過程如下:
如果傳入的是head.next(相當於從4開始翻轉),情況如下:
首先讓4號元素的next指向5號元素就可以了(此時的4號元素依然被head的next指着),然後讓5號元素的next指向null即可
代碼如下:
/**
* 傳入頭節點,反轉後傳回新的頭節點
*
* @param head
* @return
*/
public ListNode reverseList(ListNode head) {
// if (head == null) return null;//到最後一步了,最後爲空節點
// if (head.next == null) return head;//意味着這個鏈表只有一個節點了,翻轉了還是本身
if (head == null || head.next == null) return head;
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
遞歸的解題思路:搞清楚方法的作用,比如本題中ListNode reverseList(ListNode head)
的作用是返回翻轉後的鏈表的頭結點
(三)練習03:反轉鏈表(迭代)(頭插法)
https://leetcode-cn.com/problems/reverse-linked-list/
我們希望newHead指向1,1指向2,2指向3…
實現的步驟如下:
首先讓head的next指向newHead
然後讓newHead指向head
然後讓head指向下一個節點
效果如下:
再循環一遍,效果如下:
但是會有一個問題,一開始就讓head的next指向newHead,後面的節點就沒有被引用了,會被銷燬
所以我們需要搞一個臨時變量,讓它一開始就要指向head的next,如下:
此時再讓head的next指向newHead
再讓newHead指向head
讓head指向temp指向的節點
效果如下:
新一輪的循環開始之前,先讓temp指向head的next
代碼實現如下:
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = null;
while (head != null) {
ListNode tmp = head.next;
head.next = newHead;
newHead = head;
head = tmp;
}
return newHead;
}
(四)練習04:環形鏈表
https://leetcode-cn.com/problems/linked-list-cycle/
注意:java的引用相當於c語言的指針,這裏我們就用到快慢指針的思想
判斷一個鏈表是否有環的步驟如下:
假設有一個環形鏈表
首先用slow(慢指針)指向head
再用fast(快指針)指向head的next
注意:慢指針和快指針的初始位置不重要
慢指針一次走一步,快指針一次走兩步,最終它們都會進入環路,由於速度不一致,最終肯定會相遇
注意:如果fast(快指針)先指null(空指針),則代表該鏈表沒有環
代碼如下:
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) return false;
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
//if (slow == fast) return true;
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;//剛進來肯定是不相等的,先讓它們走一輪再判斷
}
return false;
}
分析:複雜度需要看fast(快指針),大概是O(n/2),即O(n)
(五)作業題
203. 移除鏈表元素:https://leetcode-cn.com/problems/remove-linked-list-elements/
83. 刪除排序鏈表中的重複元素:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/
876. 鏈表的中間結點:https://leetcode-cn.com/problems/middle-of-the-linked-list/