2462. 雇佣 K 位工人的总代价

72 阅读1分钟

题目:
leetcode.cn/problems/to…
算法:
方法一:小顶堆
一顿操作猛如虎,一看击败5%

image.png

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没必要使用二维数组

image.png

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    
}