1. 程式人生 > >(Java)LeetCode-25. Reverse Nodes in k-Group

(Java)LeetCode-25. Reverse Nodes in k-Group

Given a linked list, reverse the nodes of a linked list k at a time and return its modified 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個節點進棧,然後按照出棧的順序連線起來,則自然反轉,最後不足k個節點,就直接返回首節點。

程式碼方面也參照了上一題的迭代方法,很簡潔。

public ListNode reverseKGroup(ListNode head, int k) {
        Stack<ListNode> st = new Stack<ListNode>();
        ListNode temp = head;
        for(int i = 0; i < k ; i++){
        	if(head != null){
        		st.push(head);
        	}else{
        		return temp;
        	}
        	head = head.next;
        }
        
        ListNode first = st.pop();
        ListNode res = first;
        for(int i = 0; i<k-1; i++){
        	first.next = st.pop();
        	first = first.next;
        }
        first.next = reverseKGroup(head,k);
		return res;
    }


但是呢,用stack一方面速度較慢,另一方面萬一記憶體溢位就不好玩了,所以我下面採用了另一種方法來反轉。其實連結串列的反轉是一個經典題目,這個過程之前也看到過,這裡只是有一點點的不一樣,即不是反轉全部連結串列,而是一部分一部分的反轉。就單部分反轉來說,思路是一樣的。

思路如下:每次都將原第一個結點之後的那個結點放在頭節點的後面,下圖是原始的單鏈表。單鏈表反轉示例圖片

  為了反轉這個單鏈表,我們先讓頭結點的next域指向結點2,再讓結點1的next域指向結點3,最後將結點2的next域指向結點1,就完成了第一次交換,順序就變成了Header-結點2-結點1-結點3-結點4-NULL,然後進行相同的交換將結點3移動到結點2的前面,然後再將結點4移動到結點3的前面就完成了反轉。

寫程式碼的時候呢,用root.next指向子連結串列裡的第一個節點,head為第一個節點,反轉一次即變成第二個幾點,從而保證他後面的節點就是下一個將被放到前面的節點。用一個臨時節點儲存root後面的節點,被交換到前面的節點將指向這個臨時節點。程式碼如下~執行時間縮短到1ms
public ListNode reverseKGroup(ListNode head, int k) {
		ListNode root = new ListNode(-1);
		root.next = head;
		ListNode res = root;
		ListNode temp = head;
		int i = 0;
		while(temp != null){
			i++;
			temp = temp.next;
		}
		while(i >= k){
			for(int j = 0 ; j < k-1; j++){
				ListNode node = root.next;
				root.next = head.next;
				head.next = root.next.next;
				root.next.next = node;
			}
			root = head;
			head = head.next;
			i-=k;
		}
		return res.next;
    }