2024-5-4——规划兼职工作

题目来源

力扣每日一题;题序:1235

我的题解

方法一 动态规划+二分查找

参考官方题解
关键在于动态转移方程的构建:
兼职工作由开始时间 startTime,结束时间 endTime和预计报酬 profit 三种属性表示。首先将兼职工作按结束时间 endTime 从小到大进行排序。使用 dp[i] 表示前 i 份兼职工作可以获得的最大报酬,即区间 [0,i−1] 的所有兼职工作可以获得的最大报酬。初始时 dp[0]=0,表示没有兼职工作时报酬为 0。那么对于 i>0,根据第 i−1 份兼职工作是否被选择,有以下转移方程:
dp [ i ] = max ⁡ ( dp [ i − 1 ] , dp [ k ] + profit [ i − 1 ] ) \textit{dp}[i] = \max(\textit{dp}[i - 1], \textit{dp}[k] + \textit{profit}[i - 1]) dp[i]=max(dp[i1],dp[k]+profit[i1])。其中 k 表示满足结束时间小于等于第 i−1份工作开始时间的兼职工作数量(因为兼职工作是按照结束时间从小到大进行排序的,所以选择第 i−1 份兼职工作后,只能继续选择前 k 份兼职工作),可以通过二分查找获得。

时间复杂度:O(nlogn),其中 n 是兼职工作的数量。排序需要 O(nlog⁡n),遍历 + 二分查找需要 O(nlog⁡n),因此总时间复杂度为 O(nlog⁡n)。
空间复杂度:O(n)。需要 O(n) 的空间来保存 dp。

public int jobScheduling(int[] startTime, int[] endTime, int[] profit) {
    int n=startTime.length;
    int[][] jobs=new int[n][3];
    for(int i=0;i<n;i++){
        jobs[i][0]=startTime[i];
        jobs[i][1]=endTime[i];
        jobs[i][2]=profit[i];
    }
    Arrays.sort(jobs,(a,b)->a[1]-b[1]);
    int[] dp=new int[n+1];
    for(int i=1;i<=n;i++){
        int k=binarySearch(jobs,i-1,jobs[i-1][0]);
        dp[i]=Math.max(dp[i-1],dp[k]+jobs[i-1][2]);
    }
    return dp[n];
}
public int binarySearch(int[][] jobs,int end,int startTime){
    int left=0,right=end;
    while(left<right){
        int mid=((right-left)>>1)+left;
        //结束时间比开始时间晚
        if(jobs[mid][1]>startTime){
            right=mid;
        //结束时间小于等开始时间
        }else{
            left=mid+1;
        }
    }
    return left;
}
方法二

时间复杂度:
空间复杂度:


有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜菜的小彭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值