牛客刷題——連結串列中的節點每K個一組反轉
阿新 • • 發佈:2021-02-08
技術標籤:牛客刷題
題目:
將給出的連結串列中的節點每 k個一組翻轉,返回翻轉後的連結串列
如果連結串列中的節點數不是 k的倍數,將最後剩下的節點保持原樣
你不能更改節點中的值,只能更改節點本身。
要求空間複雜度O(1)例如:
給定的連結串列是1->2->3->4->5
對於 k=2, 你應該返回2->1->4->3->5
對於k=3, 你應該返回3->2->1->4->5
首先解決的方法肯定是以連結串列反轉為基礎的,但是這個反轉不是反轉整個連結串列,而是反轉當前結點開始的k個節點,所以在反轉的函式中加一個對於節點的計數count和k的比較即可。
然後分析k個一組反轉的話,首先要滿足有k個,所以需要使用兩個指標left和right,當指標表示的區間長度為k的時候對以left開頭,right結尾的這一組進行反轉,在進行反轉之前要記錄好當前區間的pre節點和next節點,由於上一個連結串列區間反轉後關係變成了right->left,這裡的left節點實際上就是當前結點的pre節點,對於next節點則直接在遍歷的時候記錄即可。連結串列反轉之後,使用pre,left,right和next重新整理好連結串列之間的關係,並且更新這些節點的值,直到整個連結串列遍歷結束。
完整程式碼如下:
public ListNode reverseKGroup (ListNode head,int k) { // write code here if(head==null||head.next==null) { return head; } int count = 0; ListNode tempNow = head; ListNode now = head; //兩個結點相當於左右指標,確定反轉區間 ListNode res = new ListNode(0); //頭結點 res.next = head; ListNode next = null; //tempNow的下一個結點 ListNode pre = res; //now的上一個結點 while(now!=null) { count++; if(count%k==0) { next = now.next; ListNode temp = reverseK(tempNow, k); pre.next = now; pre = temp; temp.next = next; tempNow = next; now = next; }else { now = now.next; } } return res.next; } public ListNode reverseK(ListNode head,int k) { //反轉從head開始的k個 // write code here ListNode now = head; ListNode next = head.next; head.next = null; int count = 1; while(next!=null&&count<k) { ListNode nNext = next.next; next.next = now; now = next; next = nNext; count++; } return head; }