首页 > 其他分享 >【LeetCode 1235】规划兼职工作

【LeetCode 1235】规划兼职工作

时间:2024-05-05 16:12:28浏览次数:14  
标签:1235 endTime int 规划 兼职 排序 递推 LeetCode dp

题目描述

原题链接: LeetCode.1235 规划兼职工作

解题思路

  • 想到了按照结束时间排序后用动态规划来处理, 但是又局限在了以结束时间为维度进行递推, 又卡在了时间不连续无法高效计算到最晚结束时间范围内所有时间对应值这一问题上, 看了题解才知道用排序后的兼职工作数量为维度去递推:
    • 递推数组定义为前i个结束的兼职工作能得到的最大报酬;
    • 递推公式是 dp[i] = Math.max(dp[i - 1], dp[k] + profit[i]), 其中k是结束时间不晚于startTime[i]的最晚结束工作, 可以通过二分法在[0, i-1]范围内确认k的值;
    • dp[n]就是最终所求答案, 时间复杂度是排序所需的O(n\(log_2 n\)) + 动态规划所需的O(n\(log_2 n\)), 空间复杂度是辅助关联排序后三个输入数组的变量所需的O(n);
  • 本题是很有实际应用意义的动态规划题, 而且也用到二分法巧妙加速递推过程, 值得记录用以回顾;
  • 动态规划的思路最难的还是确认定义, 确认解出来后再看只能怪自己最初怎么想不到, 希望后面能总结出自己能快速反应抓住的技巧/规律吧。

解题代码

  • 排序+动态规划+二分:

      /**
       * 看官方题解写的代码
       * 执行用时: 27 ms , 在所有 Java 提交中击败了 73.74% 的用户
       * 内存消耗: 53.72 MB , 在所有 Java 提交中击败了 96.46% 的用户
       */
      public int jobScheduling(int[] startTime, int[] endTime, int[] profit) {
          int n = endTime.length;
          // 按结束时间将工作对应的下标排序
          Integer[] indexes = IntStream.range(0, n).boxed().toArray(Integer[]::new);
          Arrays.sort(indexes, Comparator.comparingInt(i -> endTime[i]));
          // dp[i]表示从前i份工作中能获得的最大报酬
          int[] dp = new int[n + 1];
          for (int i = 1; i <= n; i++) {
              Integer idx = indexes[i - 1];
              // 用二分法在前i-1份工作中找到结束时间不晚于第i份工作开始时间的工作是第几份
              int left = 0, right = i - 1;
              while (left < right) {
                  int mid = (left + right) >> 1;
                  if (endTime[indexes[mid]] > startTime[idx]) {
                      right = mid;
                  }
                  else {
                      left = mid + 1;
                  }
              }
              dp[i] = Math.max(dp[i - 1], dp[left] + profit[idx]);
          }
          return dp[n];
    

标签:1235,endTime,int,规划,兼职,排序,递推,LeetCode,dp
From: https://www.cnblogs.com/coding-memory/p/18173565

相关文章

  • 106. 从中序与后序遍历序列构造二叉树(leetcode)
    https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/要点是明白中序和后序如何构造二叉树的,并且需要理清当前递归函数的语义,不要一开始就陷入细节,而是思考整棵树与其左右子树的关系,语义是:即构造当前节点,给当前节点左右子树赋值,明......
  • [leetcode 87 扰乱字符串] [剪枝搜索]
    importjava.util.HashMap;importjava.util.Map;classSolution{publicstaticvoidmain(String[]args){Solutionsolution=newSolution();booleanres=solution.isScramble("eebaacbcbcadaaedceaaacadccd","eadcaacabad......
  • 程序员兼职那些事儿
    最近周边发生一起程序员兼职引起的纠纷事件,作为一名资深程序员的我也做过兼职,所以不禁思考作为程序员做兼职时的一些套路,以及应该遵循的原则。1、兼职引起的纠纷最近笔者发现周边有些程序员常年利用上班时间做兼职工作,还拉拢一些在职同事一起参与,而且做兼职的过程中无意间泄露......
  • 力扣1235 2024.5.4
    原题网址:https://leetcode.cn/problems/maximum-profit-in-job-scheduling/submissions/529098063/个人难度评价:1600分析:一眼DP,考虑DP顺序,DP递推式与边界十分类似背包,记i为第i段时间,显然有dp[i]=max(dp[i-1],dp[b[i]]+p[i])由此得出递推顺序为按结束时间为第一关键字升序递推......
  • leetcode算法热题--最长连续序列
    题目给定一个未排序的整数数组nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为O(n)的算法解决此问题。示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4。示例2:输入:nums=......
  • leetcode算法热题--最长连续序列
    题目给定一个未排序的整数数组nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为O(n)的算法解决此问题。示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4。示例2:输入:nums=......
  • leetcode算法热题--盛最多水的容器
    题目给定一个长度为n的整数数组height。有n条垂线,第i条线的两个端点是(i,0)和(i,height[i])。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。说明:你不能倾斜容器。示例1:输入:[1,8,6,2,5,4,8,3,7]输出:49解释......
  • leetcode算法热题-爬楼梯
    题目假设你正在爬楼梯。需要n阶你才能到达楼顶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?示例1:输入:n=2输出:2解释:有两种方法可以爬到楼顶。1阶+1阶2阶示例2:输入:n=3输出:3解释:有三种方法可以爬到楼顶。1阶+1阶+1阶1......
  • 347. 前 K 个高频元素(leetcode)
    https://leetcode.cn/problems/top-k-frequent-elements/description/可以考虑使用HashMap+排序,不过直接使用优先队列也挺不错,可以使用大顶堆或小顶堆classSolution{publicint[]topKFrequent(int[]nums,intk){Map<Integer,Integer>map=newHas......
  • 239. 滑动窗口最大值(leetcode)
    https://leetcode.cn/problems/sliding-window-maximum/简单的滑动窗口,但是与ACM模式的维护数组不同,在leetcode定义单调队列类更加方便classMyQueue{//单调队列实现,递减Deque<Integer>deque=newLinkedList<>();voidpoll(intval){if(!deque......