Daily LeetCode – day0085 1235. Maximum Profit in Job Scheduling

import java.util.Arrays;

// 1235. Maximum Profit in Job Scheduling
class Solution {
    public int jobScheduling(int[] startTime, int[] endTime, int[] profit) {
        int n = startTime.length;
        int[][] jobs = new int[n + 1][];
        jobs[0] = new int[]{0, 0, 0};
        for (int i = 0; i < n; ++i) {
            jobs[i + 1] = new int[]{startTime[i], endTime[i], profit[i]};
        }
        Arrays.sort(jobs, (j1, j2) -> j1[1] - j2[1]);
        int[] dp = new int[n + 1];
        for (int i = 1; i <= n; ++i) {
            int j = binarySearch(i, jobs[i][0], jobs);
            dp[i] = Math.max(dp[i - 1], dp[j] + jobs[i][2]);
        }
        return dp[n];
    }

    int binarySearch(int rightest, int latestEndTime, int[][] jobs) {
        int left = 0;
        int right = rightest;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (jobs[mid][1] <= latestEndTime) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left - 1;
    }
}
学习笔记:
今天是一道困难题,需要用到动态规划 + 二分搜素。
今天做到二分搜索的时候遇到了疑惑,刚好今天六点多就结束加班了,就学习了一波。
二分搜索分为三种,搜索一个数找不到就返回-1的,搜索左边界的,搜索右边界的。

先看循环条件:
搜索一个数的话,left <= right
搜索边界的话,left < right

核心情况在于nums[mid] == target
搜索一个数的话,返回mid
搜索左边界,right = mid
搜索右边界,left = mid + 1

返回值要注意的就是
搜索左边界,返回left或right
搜索右边界,返回left - 1或right - 1
// 搜索一个数

int binarySearch(int[] nums, int target) {
    int left = 0; 
    int right = nums.length - 1; // 注意
 
    while(left <= right) {
        int mid = (right + left) / 2;
        if(nums[mid] == target)
            return mid; 
        else if (nums[mid] < target)
            left = mid + 1; // 注意
        else if (nums[mid] > target)
            right = mid - 1; // 注意
        }
    return -1;
}

// 搜索左边界

int left_bound(int[] nums, int target) {
    if (nums.length == 0) return -1;
    int left = 0;
    int right = nums.length; // 注意
    
    while (left < right) { // 注意
        int mid = (left + right) / 2;
        if (nums[mid] == target) {
            right = mid;
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid; // 注意
        }
    }
    return left;
}


// 搜索右边界

int right_bound(int[] nums, int target) {
    if (nums.length == 0) return -1;
    int left = 0, right = nums.length;
    
    while (left < right) {
        int mid = (left + right) / 2;
        if (nums[mid] == target) {
            left = mid + 1; // 注意
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid;
        }
    }
    return left - 1; // 注意
}


关于樊轶群

一个善良的理想主义者。
此条目发表在每日LeetCode分类目录。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注