我的LeetCode:https://leetcode cn.com/u/ituring/ 我的LeetCode刷題源碼[GitHub]:https://github.com/izhoujie/Algorithmcii LeetCode 25. K 個一組翻轉鏈表 題目 給你一個鏈表,每 k 個節點 ...
我的LeetCode:https://leetcode-cn.com/u/ituring/
我的LeetCode刷題源碼[GitHub]:https://github.com/izhoujie/Algorithmcii
LeetCode 25. K 個一組翻轉鏈表
題目
給你一個鏈表,每 k 個節點一組進行翻轉,請你返回翻轉後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。
如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。
示例:
給你這個鏈表:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明:
- 你的演算法只能使用常數的額外空間。
- 你不能只是單純的改變節點內部的值,而是需要實際進行節點交換。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作權歸領扣網路所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
解題思路
思路1-先分為k段,每段翻轉後拼接回去
先對原節點每k個節點分割,每個子段進行翻轉,然後再處理拼接回去;
演算法複雜度:
- 時間複雜度: $ {\color{Magenta}{\Omicron\left(n\right)}} $
- 空間複雜度: $ {\color{Magenta}{\Omicron\left(k\right)}} $
思路2-直接遞歸處理分段及分段翻轉
每k個段記錄並遞歸,從最後k個段向上遞歸翻轉拼接,節點處理比較繞;
演算法複雜度:
- 時間複雜度: $ {\color{Magenta}{\Omicron\left(n\right)}} $
- 空間複雜度: $ {\color{Magenta}{\Omicron\left(n\right)}} $
演算法源碼示例
package leetcode;
/**
* @author ZhouJie
* @date 2020年1月13日 下午10:25:53
* @Description: 25. K 個一組翻轉鏈表
*
*/
public class LeetCode_0025 {
}
// Definition for singly-linked list.
class ListNode_0025 {
int val;
ListNode_0025 next;
ListNode_0025(int x) {
val = x;
}
}
class Solution_0025 {
/**
* @author: ZhouJie
* @date: 2020年2月4日 下午3:15:23
* @param: @param head
* @param: @param k
* @param: @return
* @return: ListNode_0025
* @Description: 1-迭代;
*
*/
public ListNode_0025 reverseKGroup(ListNode_0025 head, int k) {
ListNode_0025 p1, p2, p3, newHead;
p1 = p2 = p3 = newHead = null;
int n = 1;
ListNode_0025 dummy = new ListNode_0025(0);
dummy.next = head;
while (head != null) {
dummy.next = head;
while (head != null && n < k) {
head = head.next;
n++;
}
if (n < k || head == null) {
break;
}
p2 = head;
p3 = head.next;
head.next = null;
// 翻轉一段鏈表
reverse(null, dummy.next);
if (newHead == null) {
newHead = p2;
} else {
p1.next = p2;
}
p1 = dummy.next;
p1.next = p3;
head = p3;
n = 1;
}
return newHead == null ? dummy.next : newHead;
}
/**
* @author: ZhouJie
* @date: 2020年2月4日 下午3:20:04
* @param: @param tail
* @param: @param head
* @param: @return
* @return: ListNode_0025
* @Description: 翻轉鏈表
*
*/
private ListNode_0025 reverse(ListNode_0025 tail, ListNode_0025 head) {
if (head == null) {
return tail;
}
ListNode_0025 next = head.next;
head.next = tail;
return reverse(head, next);
}
/**
* @author: ZhouJie
* @date: 2020年2月4日 下午3:26:30
* @param: @param head
* @param: @param k
* @param: @return
* @return: ListNode_0025
* @Description: 2-遞歸;
*
*/
public ListNode_0025 reverseKGroup_2(ListNode_0025 head, int k) {
ListNode_0025 now = head;
int count = 0;
while (now != null && count < k) {
now = now.next;
count++;
}
if (count == k) {
now = reverseKGroup_2(now, k);
// head是滿足連續k個的最後一段首節點,now是最後一段尾節點的下一個節點
while (count-- > 0) {
ListNode_0025 temp = head.next;
head.next = now;
now = head;
head = temp;
}
// 返回當前段處理完後的頭結點
return now;
}
return head;
}
}