給你鏈表的頭節點 head ,每 k 個節點一組進行翻轉,請你返回修改後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。
你不能只是單純的改變節點內部的值,而是需要實際進行節點交換
思路:
每k個節點翻轉一次,相當於確定左右邊界翻轉一次,既轉換成92題目
//leetcode submit region begin(Prohibit modification and deletion)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if(head == null){
return null;
}
if(k==1){
return head;
}
ListNode dummy = new ListNode(-1);
dummy.next = head;
int n = -1;
while(dummy != null){
n++;
dummy = dummy.next;
}
//System.out.println("n = " + n);
ListNode dummy1 = new ListNode(-1);
dummy1.next = head;
int[] reverseArray = new int[n];
int left ;
int right ;
for ( left = 1,right = left+k-1; right <= n; left=right+1,right = left+k-1) {
//System.out.println("left = " + left);
//System.out.println("right = " + right);
//閉區間【1,2】
dummy1 =reverseBetween(dummy1.next, left, right);
//ListNode dummy3 = new ListNode(-1);
//dummy3.next = dummy1;
//while(dummy3!=null) {
// System.out.print(" dummy3.val: " + dummy3.val);
// dummy3 = dummy3.next;
//}
}
return dummy1.next;
}
public ListNode reverseBetween(ListNode head, int left, int right) {
if (head == null || head.next == null || left == right) {
return head;
}
//虛擬節點爲了避免頭節點爲空
ListNode dummy = new ListNode(-1);
dummy.next = head;
//分別記錄要反轉的前節點和要反轉的第一個節點
ListNode currDummy = dummy;
ListNode prevDummy = null;
ListNode prev = null;
ListNode curr = null;
for (int i = 0; i < left; i++) {
prevDummy = currDummy;
currDummy = currDummy.next;
}
curr = currDummy;
//反轉範圍內的節點
for (int i = left; i <= right && curr !=null; i++){
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
//拼接節點,反轉前的結點 拼反轉後的頭結點
prevDummy.next = prev;
//反轉後的最後一個節點拼接right後的那個節點
currDummy.next = curr;
return dummy;
}
}
//leetcode submit region end(Prohibit modification and deletion)