题目:
leetcode.cn/problems/to…
算法:
方法一:小顶堆
一顿操作猛如虎,一看击败5%
import "container/heap"
func totalCost(costs []int, k int, candidates int) int64 {
// 创建两个最小heap,heap中保存cost[i]和[i],初始化从左边和右边取costs填充到heap中
// 比较两个heap中的最小值,值相同则取i最小的出heap,统计cost
heapLeft, heapRight := Heap{}, Heap{}
n := len(costs)
cost := int64(0)
i, j := 0, n - 1
for ; i < candidates && i < n; i ++ {
heap.Push(&heapLeft, []int{i, costs[i]})
}
for ; j >= n - candidates && j >= 0 && i <= j; j -- {
heap.Push(&heapRight, []int{j, costs[j]})
}
for k > 0 {
k --
leftMinCost, rightMinCost := 100001, 100001
if len(heapLeft) > 0 {
leftMinCost = heapLeft[0][1]
}
if len(heapRight) > 0 {
rightMinCost = heapRight[0][1]
}
// fmt.Println(heapLeft, heapRight)
if leftMinCost <= rightMinCost {
cost = cost + int64(leftMinCost)
heap.Pop(&heapLeft)
// fmt.Println("left",heap.Pop(&heapLeft))
if i <= j {
heap.Push(&heapLeft, []int{i, costs[i]})
i ++
}
} else {
cost = cost + int64(rightMinCost)
heap.Pop(&heapRight)
// fmt.Println("right",heap.Pop(&heapRight))
if i <= j {
heap.Push(&heapRight, []int{j, costs[j]})
j --
}
}
}
return cost
}
type Heap [][]int
func (h Heap) Len() int {return len(h)}
func (h Heap) Swap(i, j int) {h[i], h[j] = h[j], h[i]}
func (h Heap) Less(i, j int) bool {
if h[i][1] == h[j][1] {
return h[i][0] < h[j][0]
}
return h[i][1] < h[j][1]
}
func (h *Heap) Push(x interface{}) {
*h = append(*h, x.([]int))
}
func (h *Heap) Pop() interface{} {
length := len(*h)
old := *h
x := old[length - 1]
*h = old[:length - 1]
return x
}
方法二:方法一优化
为了实现“如果有多位代价相同且最小的工人,选择下标更小的一位工人“,heap没必要使用二维数组
import "container/heap"
func totalCost(costs []int, k int, candidates int) int64 {
// 创建两个最小heap,heap中保存cost[i]和[i],初始化从左边和右边取costs填充到heap中
// 比较两个heap中的最小值,值相同则取i最小的出heap,统计cost
heapLeft, heapRight := Heap{}, Heap{}
n := len(costs)
cost := int64(0)
i, j := 0, n - 1
for ; i < candidates && i < n; i ++ {
heap.Push(&heapLeft, costs[i])
}
for ; j >= n - candidates && j >= 0 && i <= j; j -- {
heap.Push(&heapRight, costs[j])
}
for k > 0 {
k --
leftMinCost, rightMinCost := 100001, 100001
if len(heapLeft) > 0 {
leftMinCost = heapLeft[0]
}
if len(heapRight) > 0 {
rightMinCost = heapRight[0]
}
// fmt.Println(heapLeft, heapRight)
if leftMinCost <= rightMinCost {
cost = cost + int64(leftMinCost)
heap.Pop(&heapLeft)
// fmt.Println("left",heap.Pop(&heapLeft))
if i <= j {
heap.Push(&heapLeft, costs[i])
i ++
}
} else {
cost = cost + int64(rightMinCost)
heap.Pop(&heapRight)
// fmt.Println("right",heap.Pop(&heapRight))
if i <= j {
heap.Push(&heapRight, costs[j])
j --
}
}
}
return cost
}
type Heap []int
func (h Heap) Len() int {return len(h)}
func (h Heap) Swap(i, j int) {h[i], h[j] = h[j], h[i]}
func (h Heap) Less(i, j int) bool {
return h[i] < h[j]
}
func (h *Heap) Push(x interface{}) {
*h = append(*h, x.(int))
}
func (h *Heap) Pop() interface{} {
length := len(*h)
old := *h
x := old[length - 1]
*h = old[:length - 1]
return x
}