开启我的LeetCode刷题日记:436. 寻找右区间

87 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

编程世界总是离不了算法

最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力

于是决定蹭着假期,加强算法和数据结构相关的知识

那怎么提升呢?

其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode刷题之旅

第一阶段目标是:200道,每天12

为了不乱,本系列文章目录分为三部分:

  1. 今日题目:xxx
  2. 我的思路
  3. 代码实现

今日题目:436. 寻找右区间

给你一个区间数组 intervals ,其中 intervals[i] = [starti, endi] ,且每个 starti 都 不同 。

区间 i 的 右侧区间 可以记作区间 j ,并满足 startj >= endi ,且 startj 最小化 。

返回一个由每个区间 i 的 右侧区间 在 intervals 中对应下标组成的数组。如果某个区间 i 不存在对应的 右侧区间 ,则下标 i 处的值设为 -1 。

  示例 1:

输入:intervals = [[1,2]] 输出:[-1] 解释:集合中只有一个区间,所以输出-1。

示例 2:

输入:intervals = [[3,4],[2,3],[1,2]] 输出:[-1,0,1] 解释:对于 [3,4] ,没有满足条件的“右侧”区间。 对于 [2,3] ,区间[3,4]具有最小的“右”起点; 对于 [1,2] ,区间[2,3]具有最小的“右”起点。

示例 3:

输入:intervals = [[1,4],[2,3],[3,4]] 输出:[-1,2,-1] 解释:对于区间 [1,4] 和 [3,4] ,没有满足条件的“右侧”区间。 对于 [2,3] ,区间 [3,4] 有最小的“右”起点。  

提示:

  • 1 <= intervals.length <= 2 * 104
  • intervals[i].length == 2
  • -106 <= starti <= endi <= 106 每个间隔的起点都 不相同

来源:力扣(LeetCode) 链接:leetcode.cn/problems/fi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的思路

根据题意,直观反应是对于intervals[i],在有序序列中从i往后找满足intervals[j][0] >= intervals[i][1]即start_j >= end_i的元素。因为返回的是元素下标,所以在排序成有序序列前,每个元素额外记录下初始的下标。数组有序后,对于每个元素,直接使用二分法,从i为左边界的下标,查找第一个start元素大于等于end_j的interval,并返回下标。

注:原本我是从i+1开始找的,但是遇到这个测试用例[[1,1],[3,4]],满足条件的小丑竟是我自己,那就从i开始找趴hhh

代码实现

/**
 * @param {number[][]} intervals
 * @return {number[]}
 */
var findRightInterval = function (intervals) {
  let len = intervals.length,
    intervals_ = [...intervals];
  for (let i = 0; i < len; i++) {
    intervals_[i].push(i); // 排序前记录初始位置下标
  }
  intervals_.sort((a, b) => a[0] - b[0]);
  let res = new Array(len).fill(-1);
  for (let i = 0; i < len; i++) {
    // 把满足start_j>=end_i的j下标放到对应的位置中去
    res[intervals_[i][2]] = binarySearch(intervals_, i, intervals_[i][1]);
  }
  return res;
};

var binarySearch = function (nums, l, target) {
  let r = nums.length - 1;
  while (l <= r) {
    let mid = (l + r) >> 1;
    if (nums[mid][0] >= target) {
      r = mid - 1;
    } else {
      l = mid + 1;
    }
  }
  // 此时的l是满足条件的第一个大于等于target的元素位置,如果l等于nums.length,说明没有元素满足该条件
  if (l === nums.length) {
    return -1;
  } else {
    return nums[l][2];
  }
};

总结

实现方式其实有很多,这里仅供参考~

由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹