困难

23.合并K个升序链表

基础:合并两个有序链表。

var mergeTwoLists = function(list1, list2) {
  const dummy = new ListNode(0)
  let curr = dummy

  while(list1 !== null && list2 !== null) {
    if (list1.val <= list2.val) {
      curr.next = list1
      list1 = list1.next
    } else {
      curr.next = list2
      list2 = list2.next
    }
    curr = curr.next
  }

  curr.next = list1 === null ? list2 : list1

  return dummy.next
}

方法一:顺序合并

// n为链表的长度,k为链表的个数
// 时间复杂度:O(k²n),两两合并
// 空间复杂度:O(1),仅定义常量
var mergeKLists = function(lists) {
  let head = null
  for(let i = 0; i < lists.length; i++) {
    head = mergeTwoLists(head, lists[i])
  }
  return head
};

方法二:分而治之

// n为链表的长度,k为链表的个数
// 时间复杂度:O(kn * logn)
// 空间复杂度:O(logk),递归时栈空间的开销
var merge = function(lists, start, end) {
  if (start === end) {
    return lists[start]
  } else if (start > end) {
    return null
  } else {
    const middle = (start + end) >> 1
    return mergeTwoLists(
      merge(lists, start, middle),
      merge(lists, middle + 1, end)
    ) 
  }
}
var mergeKLists = function(lists) {
  return merge(lists, 0, lists.length - 1)
}

25.K个一组翻转链表

// n为链表的长度
// 时间复杂度:O(n),需要(n/k)次迭代。
// 时间复杂度:O(1),仅定义常量。
var reverseList = function(head, tail) {
  let prev = null;
  let curr = head;
  while(prev !== tail) {
    const next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }
  return [tail, head];
};

var reverseKGroup = function (head, k) {
  const dummy = new ListNode(0, head);
  let pre = dummy;

  while (head) {
    let tail = pre;
    for (let i = 0; i < k; i++) {
      tail = tail.next;
      if (!tail) {
        return dummy.next;
      }
    }

    const next = tail.next;
    [head, tail] = reverseList(head, tail);
    pre.next = head;
    tail.next = next;
    pre = tail;
    head = tail.next;
  }

  return dummy.next;
};
最后更新时间:
贡献者: wangtunan