2023-10-18:用 go 语言,给定一个数组 arr,长度为 n,表示有 0~n-1 号设备, arr[i] 表示 i 号设备的型号,型号的种类从 0~k-1,一共 k 种型号, 给定一个 k*k 的矩阵 map,来表示型号
2023-10-18:用 go 语言,给定一个数组 arr,长度为 n,表示有 0~n-1 号设备,
arr[i]表示 i 号设备的型号,型号的种类从 0~k-1,一共 k 种型号,
给定一个 k*k 的矩阵 map,来表示型号之间的兼容情况,
map[a][b] == 1,表示 a 型号兼容 b 型号,
map[a][b] == 0,表示 a 型号不兼容 b 型号,
兼容关系是有向图,也就是 a 型号兼容 b 型号,不代表 b 型号同时兼容 a 型号,
如果 i 设备的型号兼容 j 设备的型号,那么可以从 i 设备修建一条去往 j 设备的线路,
修建线路的代价是 i 设备到 j 设备的距离:|i-j|,
你的目标是从 0 号设备到达 n-1 号设备,并不一定每个设备都联通,只需要到达即可。
返回最小的修建代价,如果就是无法到达返回-1。
1 <= n <= 1000,
1 <= k <= 50。
来自招商银行。
来自左程云。
答案 2023-10-18:
大体步骤:
1.创建一个二维切片 own
,长度为 k
,用于记录每个型号的设备编号。
2.创建一个二维切片 nexts
,长度为 k
,用于记录每个型号兼容的下一个型号。
3.遍历数组 arr
,将每个设备的编号添加到对应型号的 own
中。
4.遍历兼容矩阵 m
,将每个型号兼容的下一个型号添加到对应型号的 nexts
中。
5.创建一个二叉堆 heap
,并定义排序函数,按照修建代价升序排列。
6.将起始设备 (0, 0)
添加到堆中,表示从 0 号设备开始,修建代价为 0。
7.创建一个长度为 n
的布尔型切片 visited
,用于标记设备是否被访问过。
8.当堆不为空时,进行以下操作:
弹出堆顶元素
t
,表示当前位置和当前的修建代价。获取当前位置
cur
的设备编号和修建代价。如果当前位置为目标位置
n-1
,则返回当前的修建代价。将当前位置标记为已访问。
9.获取当前设备的型号 model
。
10.遍历下一个兼容的型号 nextModel
,以及拥有下一个型号 nextModel
的设备位置 nextPosition
:
11.如果无法到达目标位置,返回 -1。
12.在 main
函数中调用 minCost
函数,并输出结果。
总的时间复杂度为 ,其中 n 是设备数量,k 是型号数量。遍历拥有型号的设备位置的过程复杂度为 O(n),堆操作的复杂度为 O(logn),遍历所有可能的型号和设备位置的复杂度为 ),所以总的时间复杂度为 。
总的额外空间复杂度为 O(n),其中 n 是设备数量。需要额外的空间来存储 own
、nexts
、visited
和堆 heap
,它们的空间复杂度都为 O(n)。
go 完整代码如下:
rust 完整代码如下:
c++完整代码如下:
版权声明: 本文为 InfoQ 作者【福大大架构师每日一题】的原创文章。
原文链接:【http://xie.infoq.cn/article/02ee797484913dc940d4d9187】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论