1. 程式人生 > >Leetcode 25:Reverse Nodes in k-Group

Leetcode 25:Reverse Nodes in k-Group

pty 指針 pos top multiple 插入 num class break

  • 1.題目描述
  • 2.解題思路
  • 3.代碼實現

1.題目描述

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
題目翻譯:
給定一個鏈表,每次翻轉鏈表中的K個元素,最後返回翻轉後的鏈表。k是一個小於等於鏈表長度的整數,如果鏈表當中的節點數不是k的整數倍,那麽除了可以翻轉的那部分,剩余的不做處理。不允許改變節點的數值,只能對節點本身進行操作,同時要求常數級的空間開銷。
舉例說明:
給定一個鏈表:1->2->3->4->5
當k=2時,2->1->4->3->5
當k=3時,3->2->1->4->5

2.解題思路

這道題的難度是hard,但是解題思路很清晰:每次取出k個節點進行翻轉,註意保持好鏈表的性質,最後少於k個的節點不做處理。那麽它的難點在哪裏? 就是你怎麽使用常數級的空間開銷來實現一個鏈表的反轉,同時保持鏈表單向鏈接的性質!!此處是重點:在數據結構的單鏈表部分,單鏈表的插入有頭插法和尾插法兩種,這裏就是利用頭插法實現單鏈表的翻轉。 何為頭插法,請點擊這裏,看詳細的解析。
在處理鏈表問題的時候,一般我們會給鏈表加上頭指針,註意和頭結點區別。因為頭指針在處理邊界問題的時候比較方便,這道題目也用到這一點,同時需要一些指針來保存要翻轉的部分鏈表開始和結束的位置。

-1->1->2->3->4->5
 |           |
pre         next

-1->3->2->1->4->5
          |  |
         pre next

3.代碼實現

  1. 單獨實現頭插法
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
     public ListNode reversek(ListNode pre,ListNode end) {
    	ListNode l1 = pre.next;//pre起到頭指針的作用
    	ListNode l2 = l1.next;
    	while
(l2 != end) { //pre.next = l2.next; l1.next = l2.next;//取出l2 l2.next = pre.next;//把l2放在頭結點的位置 pre.next = l2;//保持鏈表性質 l2 = l1.next;//更新l2位置 } return l1; } public ListNode reverseKGroup(ListNode head, int k) { if(head==null) return null; if(k==0||k==1||head.next==null)//特殊情況的判斷 return head; ListNode dum = new ListNode(-1);//java裏不知道怎麽叫,頭指針? dum.next = head; ListNode pre = dum,cur = head; int count=0; while(cur!=null) { ListNode p = pre.next; count = k; while(count!=0 && p!=null){ count--; p = p.next; }//每次while循環的步長是k if(count>0) break; if(count==0){ pre = reversek( pre,p);//頭插法處理 cur = pre.next;//下一次翻轉開始位置 } } return dum.next; } }
  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)
    		return null;
    	if(k==0||k==1||head.next==null)
        	return head;
    	ListNode dum = new ListNode(-1);
    	dum.next = head;
    	ListNode pre = dum,cur =head;
    	int count=0;
    	while(cur!=null){//遍歷鏈表,獲得長度
            count++;
            cur= cur.next;
        }
        System.out.println(count);
        while(count>=k){//頭插法,註意是>=
            cur = pre.next;
            for(int i = 0;i<k-1;i++){//註意這裏循環的次數是k-1次,是個坑
                ListNode t = cur.next;
                cur.next  = t.next;
                t.next = pre.next;
                pre.next = t;
            }
            pre = cur;
            count -=k;
        }
         return dum.next;
    }

}
  1. 未通過代碼,突發奇想使用Stack壓棧和出棧的過程就完成了翻轉,思路更簡單,但是想想也不太可能當k很大的時候,肯定不符合條件,不通過的原因是超時,代碼如下:
/**
 * 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)
    		return null;
    	//if(k==0||k==1||head.next==null)
        //	return head;
    	ListNode dum = new ListNode(-1);
    	dum.next = head;
    	ListNode pre = dum,cur =pre;
    	int count=0;
    	Stack<ListNode> tmp = new Stack<ListNode>();
         while(cur!=null){
            count =k;
             while(count!=0 && cur != null){
                 cur=cur.next;
                 count--;
                 tmp.push(cur);
             }
             if(count>0)
                 break;
             if(count==0){
                 while(!tmp.empty()){
                     pre.next = tmp.pop();
                     pre = pre.next;
                 }
             }
             cur = pre;
         }
        
         return dum.next;
    }

}

技術分享

Leetcode 25:Reverse Nodes in k-Group