Leetcode 826. 安排工作以达到最大收益

这篇博客详细介绍了LeetCode第826题的最大收益工作分配问题的解决方案。通过构建利润映射,排序难度,以及使用二分查找优化,实现高效找出每个工人能做的最高利润工作。同时,文章对比了不同方法的实现,包括直接映射、封装Work结构体和利用Go库的二分查找功能。
摘要由CSDN通过智能技术生成

Leetcode 826. 安排工作以达到最大收益

1. 问题描述

在这里插入图片描述
在这里插入图片描述

2. 思路

3. 代码

func maxProfitAssignment(difficulty []int, profit []int, worker []int) int {
    var res int
    profitMap := make(map[int]int, 0)
    length := len(profit)
    for i := 0; i < length; i++ {
         _, ok := profitMap[difficulty[i]]
        if !ok {
            profitMap[difficulty[i]] = profit[i]
        } else {
            profitMap[difficulty[i]] = max(profit[i], profitMap[difficulty[i]])
        }
    }
    sort.Ints(difficulty)
    lenWorker := len(worker)
    for i := 0; i < lenWorker; i++ {
        max := 0
        index := getMaxWorkIndex(difficulty, worker[i])
        for j := 0; j < index + 1; j++ {
            if profitMap[difficulty[j]] > max {
                max = profitMap[difficulty[j]]
            }
        }
        res += max
    }
    return res
}

func getMaxWorkIndex(difficulty []int, worker int) int {
    i := 0
    for i < len(difficulty) && difficulty[i] <= worker {
        i++
    }
    return i - 1
}

func max(a, b int) int {
    if a < b {
        a = b
    }
    return a
}

  还可以将Difficulty数组和Profit数组的元素封装为一个Work数组,进而满足对Difficulty排序时,Profit数组和Difficulty能够保持对应关系

type Work struct {
    Difficulty int
    Profit int
}

func maxProfitAssignment(difficulty []int, profit []int, worker []int) int {
    var res int
    
    works := make([]Work, len(difficulty))
    for i := 0; i < len(difficulty); i++ {
        works[i] = Work {
            Difficulty: difficulty[i],
            Profit: profit[i],
        }
    }
    sort.Slice(works, func(i, j int) bool {
        return works[i].Difficulty < works[j].Difficulty
    })

    for i := 0; i < len(worker); i++ {
        max := 0
        index := getMaxWorkIndex(works, worker[i])
        for j := 0; j < index + 1; j ++ {
            if works[j].Profit > max {
                max = works[j].Profit
            }
        }

        res += max
    }
    return res
}

func getMaxWorkIndex(works []Work, worker int) int {
    i := 0
    for i < len(works) && works[i].Difficulty <= worker {
        i++
    }
    return i - 1
}

  使用go库函数中的二分查找(类似lower_bound),查找每一个worker能做工作的最大索引位置。

type Work struct {
    Difficulty int
    Profit int
}

func maxProfitAssignment(difficulty []int, profit []int, worker []int) int {
    var res int
    
    works := make([]Work, len(difficulty))
    for i := 0; i < len(difficulty); i++ {
        works[i] = Work {
            Difficulty: difficulty[i],
            Profit: profit[i],
        }
    }
    sort.Slice(works, func(i, j int) bool {
        return works[i].Difficulty < works[j].Difficulty
    })

    for i := 0; i < len(worker); i++ {
        max := 0
        index := sort.Search(len(works), func(k int) bool {return works[k].Difficulty > worker[i]}) - 1
        for j := 0; j <= index; j++ {
            if works[j].Profit > max {
                max = works[j].Profit
            }
        }
        res += max
    }
    return res
}

  注意!!!sort.Search(n int,f func(i int) bool) int该函数使用二分查找的方法,会从[0, n)中取出一个值index,index为[0, n)中最小的使函数f(index)为True的值,并且f(index+1)也为True。如果无法找到该index值,则该方法为返回n。

  go库函数sort.Search中实现upper_bound代码如下:

index := sort.Search(len(works), func(k int) bool {return works[k].Difficulty > worker[i]})

  go库函数sort.Search中实现lower_bound代码如下:

index := sort.Search(len(works), func(k int) bool {return works[k].Difficulty > worker[i]}) - 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值