トピック:
リンクリストを提供します。kノードの各グループが反転します。反転したリンクリストに戻ってください。
kは正の整数であり、その値はリンクリストの長さ以下です。
ノードの総数がkの整数倍でない場合は、最後に残っているノードを元の順序のままにしてください。
例:
このリンクリストを提供します:1-> 2-> 3-> 4-> 5
k = 2の場合、次のようになります:2-> 1-> 4-> 3-> 5
k = 3の場合、次のようになります:3-> 2-> 1-> 4-> 5
説明:
アルゴリズムは一定の余分なスペースしか使用できません。
ノード内の値を変更するだけでなく、実際にノードを交換する必要があります。
アイデア:
1.最初に頭から始まるk個の要素を逆にします
2. k +1要素を先頭としてreverseKGroup関数を再帰的に呼び出します
3.上記の2つのプロセスの結果を結び付けます
コード:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function(head, k) {
if(head == null) return null;
// 区间 [a, b) 包含 k 个待反转元素
let a, b;
a = b = head;
for(let i = 0; i < k; i++) {
// 不足 k 个,不需要反转
if(b == null) return head;
b = b.next;
}
// 反转前 k 个元素
let newHead = reverse(a, b);
// 递归反转后续链表并连接起来
a.next = reverseKGroup(b, k);
return newHead;
};
// 反转区间 [a, b) 的元素,左闭右开
var reverse = function(a, b) {
let pre = null, cur = a, nxt = a;
while(cur != b) {
nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
return pre;
}