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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[Leedcode][JAVA][第25题][K个一组反转链表][链表][递归]

發(fā)布時(shí)間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leedcode][JAVA][第25题][K个一组反转链表][链表][递归] 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【問(wèn)題描述】[第25題][K個(gè)一組反轉(zhuǎn)鏈表][困難]

時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(1) ```java 給你一個(gè)鏈表,每 k 個(gè)節(jié)點(diǎn)一組進(jìn)行翻轉(zhuǎn),請(qǐng)你返回翻轉(zhuǎn)后的鏈表。k 是一個(gè)正整數(shù),它的值小于或等于鏈表的長(zhǎng)度。如果節(jié)點(diǎn)總數(shù)不是 k 的整數(shù)倍,那么請(qǐng)將最后剩余的節(jié)點(diǎn)保持原有順序。示例:給你這個(gè)鏈表:1->2->3->4->5當(dāng) k = 2 時(shí),應(yīng)當(dāng)返回: 2->1->4->3->5當(dāng) k = 3 時(shí),應(yīng)當(dāng)返回: 3->2->1->4->5說(shuō)明:你的算法只能使用常數(shù)的額外空間。 你不能只是單純的改變節(jié)點(diǎn)內(nèi)部的值,而是需要實(shí)際進(jìn)行節(jié)點(diǎn)交換。

【解答思路】

1. 圖解大法

1.鏈表分區(qū)為已翻轉(zhuǎn)部分+待翻轉(zhuǎn)部分+未翻轉(zhuǎn)部分
2.每次翻轉(zhuǎn)前,要確定翻轉(zhuǎn)鏈表的范圍,這個(gè)必須通過(guò) k 此循環(huán)來(lái)確定
3.需記錄翻轉(zhuǎn)鏈表前驅(qū)和后繼,方便翻轉(zhuǎn)完成后把已翻轉(zhuǎn)部分和未翻轉(zhuǎn)部分連接起來(lái)
4.初始需要兩個(gè)變量 pre 和 end,pre 代表待翻轉(zhuǎn)鏈表的前驅(qū),end 代表待翻轉(zhuǎn)鏈表的末尾
5.經(jīng)過(guò)k此循環(huán),end 到達(dá)末尾,記錄待翻轉(zhuǎn)鏈表的后繼 next = end.next
6.翻轉(zhuǎn)鏈表,然后將三部分鏈表連接起來(lái),然后重置 pre 和 end 指針,然后進(jìn)入下一次循環(huán)
7.特殊情況,當(dāng)翻轉(zhuǎn)部分長(zhǎng)度不足 k 時(shí),在定位 end 完成后,end==null,已經(jīng)到達(dá)末尾,說(shuō)明題目已完成,直接返回即可
時(shí)間復(fù)雜度為 O(n*K) 最好的情況為 O(n) 最差的情況未 O(n^2)
空間復(fù)雜度為 O(1)


時(shí)間復(fù)雜度:O(N) 空間復(fù)雜度:O(1)

/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/ class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (head == null || head.next == null){return head;}//定義一個(gè)假的節(jié)點(diǎn)。ListNode dummy=new ListNode(0);//假節(jié)點(diǎn)的next指向head。// dummy->1->2->3->4->5dummy.next=head;//初始化pre和end都指向dummy。pre指每次要翻轉(zhuǎn)的鏈表的頭結(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)。end指每次要翻轉(zhuǎn)的鏈表的尾節(jié)點(diǎn)ListNode pre=dummy;ListNode end=dummy;while(end.next!=null){//循環(huán)k次,找到需要翻轉(zhuǎn)的鏈表的結(jié)尾,這里每次循環(huán)要判斷end是否等于空,因?yàn)槿绻麨榭?#xff0c;end.next會(huì)報(bào)空指針異常。//dummy->1->2->3->4->5 若k為2,循環(huán)2次,end指向2for(int i=0;i<k&&end != null;i++){end=end.next;}//如果end==null,即需要翻轉(zhuǎn)的鏈表的節(jié)點(diǎn)數(shù)小于k,不執(zhí)行翻轉(zhuǎn)。if(end==null){break;}//先記錄下end.next,方便后面鏈接鏈表ListNode next=end.next;//然后斷開(kāi)鏈表end.next=null;//記錄下要翻轉(zhuǎn)鏈表的頭節(jié)點(diǎn)ListNode start=pre.next;//翻轉(zhuǎn)鏈表,pre.next指向翻轉(zhuǎn)后的鏈表。1->2 變成2->1。 dummy->2->1pre.next=reverse(start);//翻轉(zhuǎn)后頭節(jié)點(diǎn)變到最后。通過(guò).next把斷開(kāi)的鏈表重新鏈接。start.next=next;//將pre換成下次要翻轉(zhuǎn)的鏈表的頭結(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)。即startpre=start;//翻轉(zhuǎn)結(jié)束,將end置為下次要翻轉(zhuǎn)的鏈表的頭結(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)。即startend=start;}return dummy.next;}//鏈表翻轉(zhuǎn)// 例子: head: 1->2->3->4public ListNode reverse(ListNode head) {//單鏈表為空或只有一個(gè)節(jié)點(diǎn),直接返回原單鏈表if (head == null || head.next == null){return head;}//前一個(gè)節(jié)點(diǎn)指針ListNode preNode = null;//當(dāng)前節(jié)點(diǎn)指針ListNode curNode = head;//下一個(gè)節(jié)點(diǎn)指針ListNode nextNode = null;while (curNode != null){nextNode = curNode.next;//nextNode 指向下一個(gè)節(jié)點(diǎn),保存當(dāng)前節(jié)點(diǎn)后面的鏈表。curNode.next=preNode;//將當(dāng)前節(jié)點(diǎn)next域指向前一個(gè)節(jié)點(diǎn) null<-1<-2<-3<-4preNode = curNode;//preNode 指針向后移動(dòng)。preNode指向當(dāng)前節(jié)點(diǎn)。curNode = nextNode;//curNode指針向后移動(dòng)。下一個(gè)節(jié)點(diǎn)變成當(dāng)前節(jié)點(diǎn)}return preNode;}}
2. 遞歸

public ListNode reverseKGroup(ListNode head, int k) {if (head == null || head.next == null) {return head;}ListNode tail = head;for (int i = 0; i < k; i++) {//剩余數(shù)量小于k的話,則不需要反轉(zhuǎn)。if (tail == null) {return head;}tail = tail.next;}// 反轉(zhuǎn)前 k 個(gè)元素ListNode newHead = reverse(head, tail);//下一輪的開(kāi)始的地方就是tailhead.next = reverseKGroup(tail, k);return newHead;}/*左閉又開(kāi)區(qū)間*/private ListNode reverse(ListNode head, ListNode tail) {ListNode pre = null;ListNode next = null;while (head != tail) {next = head.next;head.next = pre;pre = head;head = next;}return pre;}

【總結(jié)】

1.鏈表題目多畫圖 ,畫圖大法好
2.整條鏈表翻轉(zhuǎn)
例子: head: 1->2->3->4public ListNode reverse(ListNode head) {//單鏈表為空或只有一個(gè)節(jié)點(diǎn),直接返回原單鏈表if (head == null || head.next == null){return head;}//前一個(gè)節(jié)點(diǎn)指針ListNode preNode = null;//當(dāng)前節(jié)點(diǎn)指針ListNode curNode = head;//下一個(gè)節(jié)點(diǎn)指針ListNode nextNode = null;while (curNode != null){nextNode = curNode.next;//nextNode 指向下一個(gè)節(jié)點(diǎn),保存當(dāng)前節(jié)點(diǎn)后面的鏈表。curNode.next=preNode;//將當(dāng)前節(jié)點(diǎn)next域指向前一個(gè)節(jié)點(diǎn) null<-1<-2<-3<-4preNode = curNode;//preNode 指針向后移動(dòng)。preNode指向當(dāng)前節(jié)點(diǎn)。curNode = nextNode;//curNode指針向后移動(dòng)。下一個(gè)節(jié)點(diǎn)變成當(dāng)前節(jié)點(diǎn)}return preNode;}
3.常規(guī)解法

將鏈表指針全部復(fù)制到數(shù)組進(jìn)行調(diào)整后再連接的算法

轉(zhuǎn)載鏈接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/tu-jie-kge-yi-zu-fan-zhuan-lian-biao-by-user7208t/

轉(zhuǎn)載鏈接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/di-gui-java-by-reedfan-2/

總結(jié)

以上是生活随笔為你收集整理的[Leedcode][JAVA][第25题][K个一组反转链表][链表][递归]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。