Go语言每日一练——链表篇(五)

传送门

牛客面试笔试必刷101题 ----------------合并k个已排序的链表

题目以及解析

题目

在这里插入图片描述

解题代码及解析

解析

这一道题与昨天的合并链表题目类似,但是由于有K个且时间复杂度要求控制在O(nlogn),这里主要有两种解法:一种是依旧使用归并来合并,一种则是利用堆这种数据结构来实现。

代码

方法一:堆(优先队列)

package main
import _"fmt"
import . "nc_tools"
import "container/heap"

/*
 * type ListNode struct{
 *   Val int
 *   Next *ListNode
 * }
 */

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param lists ListNode类一维数组 
 * @return ListNode类
*/
func mergeKLists( lists []*ListNode ) *ListNode {
   
    p:=hp{
   }
    for _,head:=range lists{
   
        if head!=nil{
   
           p=append(p,head)
        }
    }
    heap.Init(&p)//初始化堆
    curr:=&ListNode{
   }
    dump:=curr
    for len(p)>0{
   
        node:=heap.Pop(&p).(*ListNode)
        if node.Next!=nil{
   
           heap.Push(&p,node.Next)
        }
        curr.Next=node
        curr=curr.Next
    }
    return dump.Next
}

//定义小根堆
type hp []*ListNode

func (p hp) Len() int{
   
    return len(p)
}
func (p hp)Less(i,j int) bool{
     //通过该函数来确定小根堆还是大根堆
    return p[i].Val<p[j].Val
}

func (p hp)Swap(i,j int){
   
    p[i],p[j]=p[j],p[i]
}

func (p *hp)Push(value interface{
   }){
   
    *p=append(*p,value.(*ListNode))
}

func (p *hp)Pop() any{
   
    a:=*p
    value:=a[len(a)-1]
    *p=a[:len(a)-1]
    return value
}

方法二:分治

package main

import (
	_ "container/list"
	_ "fmt"
	. "nc_tools"
	_ "net"
)

/*
 * type ListNode struct{
 *   Val int
 *   Next *ListNode
 * }
 */

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param lists ListNode类一维数组
 * @return ListNode类
 */
func Merge(list1 *ListNode, list2 *ListNode) *ListNode {
   
	dump := &ListNode{
   }
	current := dump
	for list1 != nil && list2 != nil {
   
		if list1.Val < list2.Val {
   
			current.Next = list1
			list1 = list1.Next
		} else {
   
			current.Next = list2
			list2 = list2.Next
		}
        current=current.Next
	}
	if list1 != nil {
   
		current.Next = list1
		list1 = list1.Next
	}
	if list2 != nil {
   
		current.Next = list2
		list2 = list2.Next
	}
	current = current.Next
	return dump.Next
}

func mergeKLists(lists []*ListNode) *ListNode {
   
	m := len(lists)
	if m == 0 {
   
		return nil
	}
	if m == 1 {
   
		return lists[0]
	}
	left := mergeKLists(lists[:m/2])
	right := mergeKLists(lists[m/2:])
	return Merge(left, right)
}

总结:

这题依旧是一道合并链表题,但是简单的遍历来挨个合并会使时间复杂度上升到O(n^2),所以需要采取一些巧劲来实现,但是玩具的最好的还是使用堆来解题,可以更好了解到堆泛型在Go语言中如何去使用。

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-02-07 01:10:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-07 01:10:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-07 01:10:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-07 01:10:04       20 阅读

热门阅读

  1. Linux内核与驱动面试经典“小”问题集锦(2)

    2024-02-07 01:10:04       31 阅读
  2. git 的基本概念

    2024-02-07 01:10:04       35 阅读
  3. ECMAScript日常总结--ES2018(ES9)

    2024-02-07 01:10:04       27 阅读
  4. EasyExcel的导入导出使用

    2024-02-07 01:10:04       32 阅读
  5. 鸿蒙 WiFi 扫描流程(2)

    2024-02-07 01:10:04       28 阅读
  6. 【关于实现远程启动电脑】

    2024-02-07 01:10:04       32 阅读
  7. 企业级Spring boot项目 配置清单

    2024-02-07 01:10:04       30 阅读
  8. ubuntu上安装docker-compose踩坑记录

    2024-02-07 01:10:04       23 阅读
  9. ChatGLM3-6B可以进行模型微调吗

    2024-02-07 01:10:04       34 阅读