日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【算法】Java 中链表的基本操作

發布時間:2024/3/24 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【算法】Java 中链表的基本操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??鏈表是一種重要的數據結構,在工程項目中廣泛使用。對于鏈表,要搞清楚是否有頭節點,即第一個節點不存任何數據,只是表示鏈表的頭部,而首節點才是鏈表第一個真正存放數據的節點。通常情況下,對有頭節點的鏈表進行操作比較方便。如果原來的鏈表沒有頭節點,可以 new 一個 dummyHead 作為頭節點,這樣往往能減少大量邊界條件的判斷。下面通過幾個例題來學習鏈表。

1.力扣206.反轉鏈表[1]

給你單鏈表的頭節點 head ,請你反轉鏈表,并返回反轉后的鏈表。

示例 1:

輸入:head = [1,2,3,4,5] 輸出:[5,4,3,2,1]

反轉鏈表是鏈表中最常考到的問題。可以使用頭插法反轉鏈表。具體解法如下:

class Solution {public ListNode reverseList(ListNode head) {ListNode pre = null; // 首節點while (head != null) {ListNode next = head.next; // 臨時存儲下次要操作的節點head.next = pre; // 頭插法的要點是每次在首節點的前面插入pre = head; // 插入后的節點變成新的首節點head = next; // 取下次要操作的節點}return pre;} }

或者定義一個 dummyHead,每次在 dummyHead 的后面插入:

class Solution {public ListNode reverseList(ListNode head) {ListNode dummyHead = new ListNode(0, null);ListNode p = head;while (p != null) {ListNode next = p.next;p.next = dummyHead.next;dummyHead.next = p;p = next;}return dummyHead.next;} }
2.力扣92. 反轉鏈表 II[2]

給你單鏈表的頭指針 head 和兩個整數 left 和 right ,其中 left <= right 。請你反轉從位置 left 到位置 right 的鏈表節點,返回 反轉后的鏈表 。

示例 1:

輸入:head = [1,2,3,4,5], left = 2, right = 4 輸出:[1,4,3,2,5]

這道題和上一題基本一樣,只是需要先將指針移動到要操作的區間。

class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {// 定義一個啞節點,這樣即使 left = 0 也不需要特殊處理ListNode dummy = new ListNode(0, head);// pre 用來指向要翻轉的第一個節點ListNode pre = dummy;// 將指針移動到要反轉的第一個節點的上一個節點for (int i = 1; i < left; i++) pre = pre.next;// cur 用來指向要翻轉的第一個節點,始終將 cur 的下一個節點進行頭插ListNode cur = pre.next;// 頭插法for (int i = 0; i < right - left; i++) {ListNode next = cur.next; // 將 cur 的下一個節點取出來,準備頭插cur.next = next.next; // cur 連接到后面剩余的節點// 頭插next.next = pre.next;pre.next = next;}return dummy.next;} }

具體過程如下:

next = cur.next:

cur.next = next.next:

next.next = pre.next:

pre.next = next:

3.力扣25.K 個一組翻轉鏈表[3]

給你一個鏈表,每 k 個節點一組進行翻轉,請你返回翻轉后的鏈表。k 是一個正整數,它的值小于或等于鏈表的長度。如果節點總數不是 k 的整數倍,那么請將最后剩余的節點保持原有順序。

進階:

你可以設計一個只使用常數額外空間的算法來解決此問題嗎?
你不能只是單純的改變節點內部的值,而是需要實際進行節點交換。

示例 1:

輸入:head = [1,2,3,4,5], k = 2 輸出:[2,1,4,3,5]

示例 2:

輸入:head = [1,2,3,4,5], k = 3 輸出:[3,2,1,4,5]

若不考慮進階的要求,可以用 Map 來記錄下標:

class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (head == null) return head;int idx = 0;Map<Integer, ListNode> map = new HashMap<>();ListNode p = head;while (p != null) {map.put(idx++, p);p = p.next;}int cnt = idx / k; // idx是節點總數,cnt表示有幾個段要翻轉for (int i = 0; i < cnt; i++) {// 每段第一個節點連接到下一段第一個,防止最后一段不夠k個導致不用翻轉map.get(i * k).next = map.get((i+1) * k);// 從倒數第1個節點翻轉到倒數第k-1個for (int j = 1; j < k; j++) {map.get((i+1) * k - j).next = map.get((i+1) * k - j - 1);}if (i > 0) { // 把前面一段的第一個節點的next連接到當前一段的最后一個節點map.get((i-1) * k).next = map.get((i+1) * k - 1);}}return map.get(k - 1);} }

若考慮進階的要求,則不能借助 Map 記錄下標:

class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (head == null || head.next == null){return head;}// dummy->1->2->3->4->5ListNode dummy=new ListNode(0, head);ListNode pre=dummy; // pre指每次要翻轉的鏈表的頭結點的上一個節點ListNode end=dummy; // end指每次要翻轉的鏈表的尾節點while(end.next!=null){//循環k次,找到需要翻轉的鏈表的結尾for(int i=0;i<k&&end != null;i++){end=end.next;}//如果end==null,即需要翻轉的鏈表的節點數小于k,不執行翻轉。if(end==null) break;ListNode next=end.next; // 下一次要翻轉的鏈表end.next=null; //然后斷開鏈表ListNode start=pre.next; //記錄下要翻轉鏈表的頭節點pre.next=reverse(start);//翻轉后頭節點變到最后。通過.next把斷開的鏈表重新鏈接。start.next=next;//將pre和end初始化,換成下次要翻轉的鏈表的頭結點的上一個節點。即startpre=start;end=start;}return dummy.next;}private ListNode reverse(ListNode head) {ListNode pre = null;ListNode curr = head;while (curr != null) {ListNode next = curr.next;curr.next = pre;pre = curr;curr = next;}return pre;} }

歡迎關注公眾號。

Reference

[1]力扣206. 反轉鏈表:https://leetcode-cn.com/problems/reverse-linked-list/

[2]力扣92. 反轉鏈表 II:https://leetcode-cn.com/problems/reverse-linked-list-ii/

[3]力扣25.K 個一組翻轉鏈表:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/

總結

以上是生活随笔為你收集整理的【算法】Java 中链表的基本操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。