757

思路1:排序+贪心

先将nums按nums[i][1]进行升序排序,而后贪心地在每个区间中选取两个数。初始时,选取第一个区间的最右边两个数,即l=nums[0][1]-1和r=nums[0][1],因此res初始值设为2,而后遍历其他区间时,设当前遍历到的区间为[a,b]

  • 若l和r均在该区间内,即 l>=a&&r<=b 则无需处理
  • 若r<a,即之前选取的两个数不在当前区间内,则需要在区间[a,b]中重新选取两个数,显然应该贪心地选择最右边的两个数,因为这两个数最有可能会在后面的区间内,并更新l,r的值
  • l<a&&a<=r,即l不在当前区间内,而r在当前区间内,因此需要在当前的区间内再选择一个数,因此贪心地选择区间右端点,同时更新所选的两个点,即l=r,r=b
class Solution {
    public int intersectionSizeTwo(int[][] nums) {
        Arrays.sort(nums,(a,b)->a[1]-b[1]);
        int res=2,n=nums.length;
        int l=nums[0][1]-1,r=nums[0][1];
        for(int i=1;i<n;i++){
            if(nums[i][0]>r){
                res+=2;
                l=nums[i][1]-1;
                r=nums[i][1];
            }
            else if(nums[i][0]>l&&nums[i][0]<=r){
                res+=1;
                if(nums[i][1]==r)l=r-1;
                else{
                    l=r;
                    r=nums[i][1];
                }
            }
        }
        return res;
    }
}

class Solution:
    def intersectionSizeTwo(self, nums: List[List[int]]) -> int:
        nums.sort(key=(lambda x:x[1]))
        #print(nums)
        l,r,res=nums[0][1]-1,nums[0][1],2
        for c in nums:
            if c[0]>r:
                res+=2
                l,r=c[1]-1,c[1]
            elif l<c[0] and r>=c[0]:
                res+=1
                if r==c[1]:
                    l=c[1]-1
                else:
                    l,r=r,c[1]
        return res

思路2:线段树+贪心

先将nums按nums[i][1]进行升序排序,对于每个区间[a,b],均进行查询操作,若已选取的数在该区间内的个数为0,则选择b-1和b,若为1,则选择区间最右边的未选取的数,同时更新线段树

待补充
posted @ 2022-07-22 11:15  kris-phl  阅读(17)  评论(0)    收藏  举报