题目

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

Example:

Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5

Note:

  • Only constant extra memory is allowed.
  • You may not alter the values in the list’s nodes, only nodes itself may be changed.

题意

将给定链表中的每k个结点按逆序重新排列,不能改变结点内的值,只能改动结点本身,且只能使用0025. Reverse Nodes in k-Group (H) - 图1的空间。

思路

整体上与 0024. Swap Nodes in Pairs (M) 的解决方法相似,只是多了2个以上结点的逆序排列,因为只能使用常数的额外空间,所以不能用栈来实现逆序,直接使用插入到头结点之前的方式来实现逆序。


代码实现

Java

递归

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) { val = x; }
  7. * }
  8. */
  9. class Solution {
  10. public ListNode reverseKGroup(ListNode head, int k) {
  11. ListNode pointer = head;
  12. // 判断剩余结点数是否达到k,并找到下一个k元组的头结点
  13. for (int i = 0; i < k; i++) {
  14. if (pointer == null) {
  15. return head;
  16. }
  17. pointer = pointer.next;
  18. }
  19. ListNode nextHead = pointer; // 记录下一个k元组的头结点
  20. ListNode first = null; // 逆序排列时记录逆序链表的头结点
  21. pointer = head;
  22. // 逆序处理
  23. while (pointer != nextHead) {
  24. ListNode temp = pointer.next;
  25. pointer.next = first;
  26. first = pointer;
  27. pointer = temp;
  28. }
  29. head.next = reverseKGroup(nextHead, k);
  30. return first;
  31. }
  32. }

迭代

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) { val = x; }
  7. * }
  8. */
  9. class Solution {
  10. public ListNode reverseKGroup(ListNode head, int k) {
  11. ListNode ans = new ListNode(0);
  12. ans.next = head;
  13. ListNode root = ans; // 记录上一个k元组逆序后的最后一个结点
  14. // 统计结点数
  15. ListNode pointer = head;
  16. int num = 0;
  17. while (pointer != null) {
  18. num++;
  19. pointer = pointer.next;
  20. }
  21. pointer = ans.next;
  22. while (num >= k) {
  23. ListNode first = null; // 逆序时的头结点
  24. ListNode nextRoot = pointer; // 记录当前k元组逆序前的第一个结点
  25. // 逆序处理
  26. for (int i = 0; i < k; i++) {
  27. ListNode temp = pointer.next;
  28. pointer.next = first;
  29. first = pointer;
  30. pointer = temp;
  31. }
  32. root.next = first;
  33. root = nextRoot;
  34. num -= k;
  35. }
  36. root.next = pointer; // 将个数不足k的结点补充到链表最后
  37. return ans.next;
  38. }
  39. }

JavaScript

递归

  1. /**
  2. * Definition for singly-linked list.
  3. * function ListNode(val, next) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.next = (next===undefined ? null : next)
  6. * }
  7. */
  8. /**
  9. * @param {ListNode} head
  10. * @param {number} k
  11. * @return {ListNode}
  12. */
  13. var reverseKGroup = function (head, k) {
  14. if (head === null) {
  15. return null
  16. }
  17. let nextHead = head
  18. for (let i = 1; i <= k; i++) {
  19. if (nextHead === null) {
  20. return head
  21. }
  22. nextHead = nextHead.next
  23. }
  24. let newHead = null
  25. let tail = head
  26. while (head !== nextHead) {
  27. let tmp = head.next
  28. head.next = newHead
  29. newHead = head
  30. head = tmp
  31. }
  32. tail.next = reverseKGroup(nextHead, k)
  33. return newHead
  34. }

迭代

/**
 * 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) {
  let len = 0
  let p = head
  while (p !== null) {
    len++
    p = p.next
  }

  let dummy = new ListNode(0, head)
  let tail = dummy
  p = head
  while (len >= k) {
    let nextTail = p
    let newHead = null
    for (let i = 0; i < k; i++) {
      let tmp = p.next
      p.next = newHead
      newHead = p
      p = tmp
    }
    tail.next = newHead
    tail = nextTail
    len -= k
  }
  tail.next = p

  return dummy.next
}