給出一個鏈表,每 k 個節點一組進行翻轉,並返回翻轉後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。如果節點總數不是 k 的整數倍,那麼將最後剩餘節點保持原有順序。
示例 :
給定這個鏈表:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明 :
- 你的算法只能使用常數的額外空間。
- 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
- //涉及到鏈表指針的題目大多需要進行鏈的翻轉,如下會用一個常用的
- 1、
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* reverseKGroup(ListNode* head, int k) { ListNode* pre; ListNode* p = head; ListNode* q = head; if(!p || k == 1) return p; for(int i = 1; i < k; i ++){ if(!q->next) return head; q = q->next; } pre = p; head = q; while(p->next != head){//翻轉鏈表的核心 q = p->next; //1. 緩衝p後面的單鏈表 p->next = p->next->next; //2. 反轉單鏈表 q->next = pre; //3.讓pPre指針後移 pre = q; //4. 讓pre指針後移 } p->next = reverseKGroup(head->next, k); head->next = pre; return head; } };
2、
-
public ListNode reverseKGroup(ListNode head, int k) { if(head == null) { return null; } ListNode dummy = new ListNode(0); dummy.next = head; int count = 0; ListNode pre = dummy; ListNode cur = head; while(cur != null) { count ++; ListNode next = cur.next; if(count == k) { pre = reverse(pre, next); count = 0; } cur = next; } return dummy.next; } private ListNode reverse(ListNode pre, ListNode end) { if(pre==null || pre.next==null) return pre; ListNode head = pre.next; ListNode cur = pre.next.next; while(cur!=end) { ListNode next = cur.next;//緩衝cur後面的鏈表 cur.next = pre.next;//翻轉單鏈表 pre.next = cur;//讓pre.next的指針後移,類似於後移head cur = next;//後移cur的指針 } head.next = end; return head; }
//直接翻轉單鏈表 ListNode *listReverse(ListNode *pHead) { if(pHead == NULL) return NULL; ListNode *pCurrent ,*pPre,*pNext; //一、指針的初始化階段 pPre = pHead; pCurrent = pPre->next ; while(pCurrent) //二、反轉單鏈表的核心代碼 { pNext = pCurrent->next ; //1. 緩衝pCurrent後面的單鏈表 pCurrent->next = pPre ; //2. 反轉單鏈表 pPre = pCurrent; //3.讓pPre指針後移 pCurrent = pNext ; //4. 讓pCurrent指針後移 } //三、處理並返回頭指針 pHead->next = NULL; //把原頭結點的next域變成空指針 pHead = pPre ; //把頭結點指向最後一個結點產生新的頭結點,也就是把原單鏈表的尾結點變成頭結點 return pHead; }