leetcode 25. k個一組翻轉鏈表(Java版)

題目描述(題目難度,困難)

給出一個鏈表,每 k 個節點一組進行翻轉,並返回翻轉後的鏈表。

k 是一個正整數,它的值小於或等於鏈表的長度。如果節點總數不是 k 的整數倍,那麼將最後剩餘節點保持原有順序。

示例 :

給定這個鏈表:1->2->3->4->5

k = 2 時,應當返回: 2->1->4->3->5

k = 3 時,應當返回: 3->2->1->4->5

說明 :

  • 你的算法只能使用常數的額外空間。
  • 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。

示例代碼

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
	// 一組結點的鏈表轉置函數
	private void reverse(ListNode header, ListNode tail) {
		ListNode p = null, q = null, r = null;
		p = header.next;
		q = p.next; // 主要是要改變 q 指針的指向
		r = q.next;
		header.next = tail;
		p.next = tail.next;
		while(true){
			q.next = p;
			p = q;
			if(p == tail) break;
			q = r;
			r = r.next;
		}
	}
	public ListNode reverseKGroup(ListNode head, int k) {
		if(k <= 1){
			return head;
		}
		ListNode header = new ListNode(0);
		header.next = head;
		ListNode p = header;
		ListNode q = header;
		ListNode r = null;
		while(true){
			for(int i = 0; i < k; ++i){
				q = q.next;
				if(q == null) return header.next; // 後面的結點不夠一組,不需要翻轉,可以直接返回結果了
			}
			r = p.next;
			reverse(p, q);
			p = r;
			q = r;
		}
	}
}

思路解析

翻轉鏈表算得上是一道常見的鏈表類面試題了,題目難度本身算不上困難。這種鏈表類問題其實只要做到細心和注意指針判空,問題就應該不大。正是因爲常見,所以翻轉鏈表的代碼求解一定要熟練掌握。
鏈表類問題做到現在,總結出瞭如下兩點技巧:

  1. 處理鏈表問題時,一般都給輸入的鏈表加一個頭結點,這樣就可以在一個循環裏統一處理所有的結點,而不需要去特殊處理原本的頭節點。
  2. 處理鏈表類問題,我覺得使用 while(true){} 這種死循環最順手。因爲在你寫出循環體的代碼之前,你很難立馬準確的判斷循環截止條件是什麼,與其在寫循環體的時候老是操心 while() 裏的循環截止條件,邊寫循環體邊把循環截止條件改來改去。還不如順着循環體的思路一路順暢的寫下去,然後在需要跳出循環時,直接使用 if 語句判斷是否應該跳出循環即可,而且提前跳出循環也能避免一些不必要的麻煩。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章