【leetCode 23】 合并 K 个升序链表(分治算法)

function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
  //合并两个有序链表
  function mergeTwoLists(
    list1: ListNode | null,
    list2: ListNode | null
  ): ListNode | null {
    // 都为空,则返回[]
    if (list1 == null && list2 == null) {
      return null;
    }

    //只有一个有数据,则返回有数据的链表
    if (list1 == null || list2 == null) {
      return list1 || list2;
    }

    if (list1.val < list2.val) {
      list1.next = mergeTwoLists(list1.next, list2);
      return list1;
    } else {
      list2.next = mergeTwoLists(list1, list2.next);
      return list2;
    }
  }

  /** 深度优先搜索算法 */
  /** 分治算法 */
  function dfs(i: number, j: number): ListNode | null {
    const m = j - i;
    // 数组为空,则返回
    if (m === 0) return null;

    //数组只有一个链表,直接返回
    if (m === 1) return lists[i];
    // >> 1 运算符 是将该值的二进制形式向右移动 1位,
    // 奇数 = (该奇数 -1 /) 2 ,  偶数 = 该偶数 / 2
    // 奇数例: 5 >> 1 = (5 - 1) / 2 = 2;
    // 偶数例:6 >> 1 = 6 / 2 = 3;

    // 解释 left = dfs(i, i + (m >> 1))
    // i:   始终取数据第0条数据 , i + (m >> 1):取剩下数组一半的数据,若数据为奇数,则先 -1变成偶数
    // 例 [1,2,3,4,5]   索引 i:0, i + (m >> 1):2   就是取索引0 - 索引 1的,因为后面的2不包括在内
    const left = dfs(i, i + (m >> 1));

    // 解释  right = dfs(i + (m >> 1), j)
    // i + (m >> 1):取剩下数组一半的数据,若数据为奇数,则先 -1变成偶数   j:整个数组的长度
    // 例 [1,2,3,4,5]   索引 i + (m >> 1):2, j:5   就是取索引2 - 索引 4的,因为后面的5不包括在内
    const right = dfs(i + (m >> 1), j);

    //通过上面的操作,不断地将 数组一分为2,分完后,如果可以再分,则继续一分为2,直到无法再分了。
    //通过递归,最终 left  与 right  分别为数组细分后的两个链表。再 通过 mergeTwoLists(left, right) 这个函数,将两个链表合并
    // 最终一层一层返回到最初的链表数组上,所以最后该链表数组被分为了两个 合并后的链表,再将最后这两个链表合并,则全部合并完成

    return mergeTwoLists(left, right);
  }

  return dfs(0, lists.length);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值