待实现
扫描线段树,求矩形面积,周长。
TODO
区间
729. My Calendar I(Medium)
思路:使用TreeSet记录插入顺序,每次要插入新的区间时,判断该区间是否已经出现
状态:错误
Cases:
["MyCalendar","book","book"]
[[],[33,41],[33,42]]
["MyCalendar","book","book","book","book"]
[[],[47,50],[33,41],[39,45],[33,42]]
["MyCalendar","book","book","book"]
[[],[10,20],[15,25],[20,30]]
["MyCalendar","book","book","book","book","book","book","book","book","book","book"]
[[],[47,50],[33,41],[39,45],[33,42],[25,32],[26,35],[19,25],[3,8],[8,13],[18,27]]
知识点:TreeSet使用NavigableSet,headSet,tailSet
import java.util.NavigableSet;
class MyCalendar {
TreeSet<int[]> set;
public MyCalendar() {
set = new TreeSet<>((int[] a,int[] b)->{
return a[0] - b[0];
});
}
public boolean book(int start, int end) {
if(end<=start)return false;
int[] range = new int[]{start,end};
NavigableSet<int[]> subSet = set.tailSet(range,true); // >=range
if(!subSet.isEmpty()){
int[] r = subSet.pollFirst();
// range[0] < range[1] <= r[0] < r[1] ....
if(r[0]<end)return false;
}
NavigableSet<int[]> headSet = set.headSet(range,false);// <range
if(!headSet.isEmpty()){
int[] r = headSet.pollLast();
// r[1] <= range[0] < range[1]
if(r[1]>start)return false;
}
set.add(range);
return true;
}
}
/**
* Your MyCalendar object will be instantiated and called as such:
* MyCalendar obj = new MyCalendar();
* boolean param_1 = obj.book(start,end);
*/
数组
274. H-Index(Medium)
思路:由大到小尝试每一个可能的h-index,然后测试大于等于h的数量应当大于等于h,小于等于h的数量应当大于等于N-h.
关键点:需要思考清楚H-Index的取值范围
状态:通过,44%
Cases:
[3,0,6,1,5]
[100]
[1,1]
class Solution {
public int hIndex(int[] citations) {
// for sorted array, if array is odd,
// N-h, if h=0,
// h is h, N-h less than h
// if h=0, that's a candidate
// if h=1, means at least 1,other N-1 is 0
// if h=2, means at least 2
if(citations.length==0)return 0;
Arrays.sort(citations);
int p = citations[0], r=citations[citations.length-1];
// 0 1 3 5 6
// h=3, n=5,idx1=3,idx2=1, 2-2=0, 2*3-5=1
for(int i=r;i>=0;--i){
if(isHindex(citations,i))return i;
}
return 0;
// if h is h-index,
// 1 2 3 ... h1 h2 h3
// if h increase,means more
// 1 2 3 3 3
// 4
// count(>=h)=h, count(<=h)=N - h, count(=h) can be shared
// count(>h) - count(<h) = 2h - N
//
// argmax(target==e)
// while(p<r){
// int m = p+(r-p)/2;
// int d = isHindex(citations,m);
// if(d==0)return m;
// if(d<0)
// }
}
// <0, means h is too large
// =0 ,means h matches
// >0, means h is too small
boolean isHindex(int[] citations,int h){
int idx1 = lowestIndex(citations,h);
int idx2 = highestIndex(citations,h);
// count(>=h) >= h
// count(<=h) >= N - h
return (citations.length-idx1)>=h && (idx2+1)>=citations.length - h;
//return citations.length - idx1 - h;
// count(>h) - count(<h) - (2h-N)
//
// return (citations.length - idx1 - idx2-1) - 2*h + citations.length;
}
// argmin(target > e)
// if all targeg<e, return n
int lowestIndex(int[] arr,int e){
int p=0,r=arr.length;
while(p<r){
int m = p + (r-p)/2;
if(arr[m]>=e) r=m;
else p=m+1;
}
return p;
}
// argmax(target < e)
// if all target>=e, return -1
int highestIndex(int[] arr,int e){
int p=-1,r=arr.length-1;
while(p<r){
int m = p+(r+1-p)/2;
if(arr[m]<=e) p=m;
else r=m-1;
}
return p;
}
}