当前位置: 首页 > news >正文

LeetCode--23. 合并 K 个升序链表【堆和分治】

23. 合并 K 个升序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。


正文

这道题有多种解决方案

比较容易,又比较直观的就是堆排序,将每个节点加入最小根堆中,依次弹出加入最后的链表,就可得出答案,事实上,并不需要每次都将所有链表加入,只需要最开始将每个链表的头节点加入,然后在弹出链表时,直接将弹出的节点的下一个节点再加入堆即可,这样能够有效节省空间。

代码如下:

func mergeKLists(lists []*ListNode) *ListNode {
    lh := &ListHeap{}
    heap.Init(lh)
    for _, node := range lists {
        if node != nil {
            heap.Push(lh, node)
        }
    }
    dummy := &ListNode{}
    tmp := dummy
    for lh.Len() > 0 {
        Node := heap.Pop(lh).(*ListNode)
        tmp.Next = Node
        tmp = tmp.Next
        if Node.Next != nil {
            heap.Push(lh, Node.Next)
        }
    }
    return dummy.Next
}

type ListHeap []*ListNode

func (l *ListHeap) Len() int {
	return len(*l)
}

func (l *ListHeap) Less(i, j int) bool {
	return (*l)[i].Val < (*l)[j].Val
}

func (l *ListHeap) Swap(i, j int) {
	(*l)[i], (*l)[j] = (*l)[j], (*l)[i]
}

func (l *ListHeap) Push(x any) {
	*l = append(*l, x.(*ListNode))
}

func (l *ListHeap) Pop() any {
	res := (*l)[len(*l)-1]
	*l = (*l)[:len(*l)-1]
	return res
}

堆排序不用ide也太难写了~

分治

跟归并排序的思路类似,将链表切片分成两部分,分别合并成一个链表,再将这两个链表进行合并。

可以理解为:

	链表1  链表2    链表3    链表4
	|		  |		|		  |
	|		  |		|		  |
	|		  |		|		  |
	|		  |		|		  |
	+————+————+     +————+————+
		 |			 	 |
		 链表			链表
		 +————————+——————+
          		  |
				  |
				最终链表

代码如下:

func mergeKLists(lists []*ListNode) *ListNode {
    return Merge(lists, 0, len(lists) - 1)
}

func Merge(lists []*ListNode, l int, r int) *ListNode {
    if l == r {
        return lists[l]
    } else if l > r {
        return nil
    }
    mid := (l + r) / 2
    return MergeTwoLists(Merge(lists, l, mid), Merge(lists, mid + 1, r))
}

func MergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
    dummy := &ListNode{}
    tmp := dummy
    for list1 != nil && list2 != nil {
        if list1.Val > list2.Val {
            tmp.Next = list2
            tmp = tmp.Next
            list2 = list2.Next
        } else {
            tmp.Next = list1
            tmp = tmp.Next
            list1 = list1.Next
        }
    }
    if list1 != nil {
        tmp.Next = list1
    }
    if list2 != nil {
        tmp.Next = list2
    }
    return dummy.Next
}

相关文章:

  • 从零开始部署DeepSeek:基于Ollama+Flask的本地化AI对话系统
  • Everything——你的文件搜索效率革命
  • 如何在 VS Code 中快速使用 Copilot 来辅助开发
  • Java高频面试之SE-22
  • 【LeetCode】560.和为K的子数组
  • 使用 MySQL 从 JSON 字符串提取数据
  • 内部知识库:安全协作驱动数字化转型新路径
  • 【Linux AnolisOS】关于Docker的一系列问题。尤其是拉取东西时的网络问题,镜像源问题。
  • 百达翡丽(Patek Philippe):瑞士制表的巅峰之作(中英双语)
  • C++和OpenGL实现3D游戏编程【总览】
  • spring cloud 微服务部署(2025年)第一章:Nacos、LoadBalancer、GateWay、Ribbon集成之Nacos部署
  • 鼠标悬浮到某个 <li> 元素时,将 hoverLiData 更新为当前 item 的 id
  • mac 本地安装deepseek
  • Flutter:动态表单(在不确定字段的情况下,生成动态表单)
  • Linux 进程控制(进程创建,进程等待)
  • 手机功耗BugReport字段含义介绍
  • 软件考研,选择华科还是科软?
  • Java与C语言中取模运算符%的区别对比
  • 如何使用 Ollama 和 Docker 设置 DeepSeek
  • Query String 传递 json 对象参数、map参数
  • 多图|多款先进预警机亮相雷达展,专家:中国预警机已达世界先进水平
  • 解放日报:“感觉全世界人都在上海买买买”
  • 解锁儿时愿望!潘展乐战胜孙杨,全国冠军赛男子400自夺冠
  • 又一例!易方达基金张坤卸任副总职务,将专注于投资管理工作
  • 病重老人取钱在银行门口去世,家属:已协商一致
  • 巴基斯坦与印度停火延长至18日