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,则选择区间最右边的未选取的数,同时更新线段树
待补充

浙公网安备 33010602011771号