• [LeetCode 436.] Find Right Interval


    LeetCode 436. Find Right Interval

    一道需要自定义比较函数的二分查找题。
    这里重点展示自定义比较,给出比较函数、比较器、lambda三种写法。

    题目描述

    You are given an array of intervals, where intervals[i] = [starti, endi] and each starti is unique.

    The right interval for an interval i is an interval j such that startj >= endi and startj is minimized.

    Return an array of right interval indices for each interval i. If no right interval exists for interval i, then put -1 at index i.

    Example 1:

    Input: intervals = [[1,2]]
    Output: [-1]
    Explanation: There is only one interval in the collection, so it outputs -1.

    Example 2:

    Input: intervals = [[3,4],[2,3],[1,2]]
    Output: [-1,0,1]
    Explanation: There is no right interval for [3,4].
    The right interval for [2,3] is [3,4] since start0 = 3 is the smallest start that is >= end1 = 3.
    The right interval for [1,2] is [2,3] since start1 = 2 is the smallest start that is >= end2 = 2.

    Example 3:

    Input: intervals = [[1,4],[2,3],[3,4]]
    Output: [-1,2,-1]
    Explanation: There is no right interval for [1,4] and [3,4].
    The right interval for [2,3] is [3,4] since start2 = 3 is the smallest start that is >= end1 = 3.

    Constraints:

    • 1 <= intervals.length <= 2 * 104
    • intervals[i].length == 2
    • -106 <= starti <= endi <= 106
    • The start point of each interval is unique.

    解题思路

    题目限定了每个时间段的开始时间是唯一的,让我们去找每个结束时间之后的下一个最早的开始时间。
    我们可以首先按开始时间进行排序,然后对于每个结束时间,使用二分查找找出开始时间即可。
    这里,下一个开始时间可以和当前结束时间相同,所以选用的应该是 lower_bound。
    对于从开始时间到原始下标的对应,我们可以单独使用一个map做映射,或者使用pair将开始时间直接和下标打包到一起。为了展示不同类型的自定义比较器写法,我们这里使用第二种方法。

    我们可以自定义比较器,根据 cplusplus.com 所说,This can either be a function pointer or a function object。也就是说我们可以传入一个比较函数,或者手写一个 struct 并重载 () 运算符,当然我们也可以直接使用 lambda
    cppreference.com 给出了比较器中参数类型的对应关系:

    • 第一个参数是容器元素类型;
    • 第二个参数是目标元素类型;
      为什么要区分两种不同类型呢,因为我们这两种元素可以是不同类型的,如本题中我们的 target 是一个 int,而 elementpair<int,int> 或者 vector<int>

    参考代码

    lambda写法直接在行内写函数体,比较紧凑,类型也容易对应:

    /*
     * @lc app=leetcode id=436 lang=cpp
     *
     * [436] Find Right Interval
     */
    
    // @lc code=start
    class Solution {
    public:
        vector<int> findRightInterval(vector<vector<int>>& intervals) {
            assert(!intervals.empty());
    
            size_t n = intervals.size();
            vector< pair<int,int> > v(n);
            for (int i=0; i<n; i++) {
                v[i] = { intervals[i][0], i };
            }
            sort(v.begin(), v.end());
            vector<int> res(n);
            for (int i=0; i<n; i++) {
                auto it = lower_bound(v.begin(), v.end(), intervals[i][1],
                    [&](const pair<int,int>& p, const int& target){ return p.first < target; });
                if (it != v.end()) {
                    res[i] = it->second;
                } else {
                    res[i] = -1;
                }
            }
            return res;
        } // AC
    };
    // @lc code=end
    

    或者使用比较函数和比较器,这里只给出需要修改的部分代码:

    // 比较函数写法:
        static bool cmp(const pair<int,int>& p, const int& target){
            return p.first < target;
        }
        auto it = lower_bound(v.begin(), v.end(), intervals[i][1], cmp); // AC
    
    // 比较器写法:
        struct comp {
            bool operator()(const pair<int,int>& p, const int& target) {
                return p.first < target;
            }
        };
        auto it = lower_bound(v.begin(), v.end(), intervals[i][1], comp()); // AC
    
  • 相关阅读:
    Firebird开源管理工具
    ionic3使用echarts
    ionic3安卓平台引用高德地图
    ionic3安卓版release发布
    sequelize的get/post方法例子
    sequelize查询数据的日期格式化
    sequelize的mssql配置
    cordova插件列表
    ionic3使用cordova创建自定义插件
    koa2+log4js+sequelize搭建的nodejs服务
  • 原文地址:https://www.cnblogs.com/zhcpku/p/14588338.html
Copyright © 2020-2023  润新知