区间题目总结

1.leetcode252  会员题

 这道题目其实就是判断是否存在重叠区间

class Solution
{
    public boolean canAttendMeetings(int[][] nums)
    {
        // 将区间按照会议开始时间进行升序排序
        Arrays.sort(nums, (a, b) -> a[0] - b[0]);

        //两两比较相邻的两个数组,如果后面数组的第一个元素比前面数组的第二个元素要小,那说明就有重叠
        for (int i = 0; i < nums.length-1; i++) 
        {
            if (numss[i][1] > intervals[i+1][0])
            {
                return false;
            }
        }
        return true;
    }
}

2.力扣56 合并区间

 我们开了一个新数组result

现在判断nums数组的A区间是直接加到result数组里面(B的第二个数比A的第一个数小)

还是需要合并A,B两个区间(B的第二个数大于等于A的第一个数)

class Solution
{
    public int[][] merge(int[][] nums)
    {
        if(nums.length<=1)   return nums;

        Arrays.sort(nums,(a,b)->a[0]-b[0]);

        //开一个和初始数组大小一样的数组result
        int[][] result=new int[nums.length][2];

        //将nums中第一个区间加入到result数组里面
        result[0][0]=nums[0][0];
        result[0][1]=nums[0][1];

        int index=0;//记录此时到了result数组的第几个位置了

        for(int i=1;i<nums.length;i++)
        {
            //遍历原数组的每一个区间,将这个区间A和result数组目前为止的最后一个区间B进行比较
            //如果B区间的第二个数小于A区间的第一个数,那就直接把A区间加入到result数组中
            //如果B区间的第二个数大于等于A区间的第一个数,那说明两个区间有交集,那就进行合并

            //进行合并
            if(result[index][1]>=nums[i][0])
            {
                result[index][1]=Math.max(nums[i][1],result[index][1]);
            }
            else//没有重叠的话,直接把这个区间加入到result数组里面
            {
                index++;
                result[index][0]=nums[i][0];
                result[index][1]=nums[i][1];
                //上面两行其实result[index]=nums[i]即可
            }
        }
        return Arrays.copyOf(result,index+1);//最后返回的数组长度是索引+1,因为索引从0开始
    }
}

3.力扣435  字节一面原题

核心:两个区间两个区间进行比较

当两个区间没有重叠的时候,不需要删除区间

当两个区间有重叠的时候,删除结束晚的区间,保留结束早的区间(所以这是使用了贪心算法)

class Solution
{
    public int eraseOverlapIntervals(int[][] intervals)
    {
        //按区间数组中每个区间的起始时间从小到大排序
        Arrays.sort(intervals, (a, b) -> (a[0] - b[0]));

        int result = 0;

        int end = intervals[0][1];

        //两个区间两个区间进行比较
        for(int i = 1; i < intervals.length; i++)
        {
            //上一个区间的结束时间小于下一个区间的开始时间,这表示和下一个区间没有重叠
            if(end <= intervals[i][0])
            {
                 end = intervals[i][1];
            }
            //上一个区间的结束时间大于下一个区间的开始时间,表示当与下一个区间有重叠
            //此时保留结束早的区间,删除那个结束晚的区间,所以要删除的区间加一
            else
            {
                end = Math.min(end, intervals[i][1]);//选择结束早的区间,
                result++;
            }
        }

        return result;
    }
}

4. 给你多个形如[start,end]的闭区间,求出最多有几个互不相交的区间

比如[1,3],[2,4].[3,6]三个区间,最多有两个区间互不相交

这个问题在生活中的应用广泛,比如你今天有好几个活动,每个活动都可以用区间 [start, end] 表示开始和结束的时间,请问你今天最多能参加几个活动呢?(你一个人不能同时参加两个活动)

有很多种贪心的设想

(1)哪个会议开始的早就参加哪个会,一直贪下去

(2)哪个会议时间短就参加哪个会,一直贪下去

(3)哪个会议结束的早,就参加哪个会,一直贪下去

最终发现第三种贪心策略是对的

step1:从所有区间中找到结束最早的那个区间(也就是end最小的那个区间),假设这个区间是x

step2:然后将所有和这个x区间相交(有重叠)的区间都从区间集合里删除

重复步骤1,2,直到区间集合为空,之前选出的那些x的数量就是最多可以参加的活动数

  //current表示滑到哪个会议了(第0个会议,第1个会议,第2个会议......),

index表示是和第几个会议进行比较

result用来统计总共可以参加几个会议

Arrays.sort(nums,(a,b)->(a[1]-b[1]) )

int  index=0;
int  current=1; 
int  result=1;

while(current<nums.length-1)
{
   while(nums[current][0]<nums[index][1])//current一直滑到和index这个区间没有重叠的为止
   {
        current++;
   }
   index=current;
   result++;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值