LeetCode 2251. 花期内花的数目

2251. 花期内花的数目

【前缀和+TreeMap+二分】这道题显然是一道前缀和的题,但是我们发现start和end的值非常大,但是区间个数却不多,也就是说过于离散了。那么开一个start到end的数组显然是行不通的,所以我们可以用哈希表来解决这种离散问题。

使用TreeMap来记录这样的键值对,由于TreeMap是有序的,所以我们可以直接遍历map的keySet来计算前缀和,查找的时候去查第一个<=查询时间的value可以。

class Solution {

    public int binarySearch(int[] arr, int target){
        int left = 0, right = arr.length - 1;
        while(left <= right){
            int mid = (left + right) >>> 1;
            if(arr[mid] > target){
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        if(right < 0) return -1;
        return arr[right];
    }

    public int[] fullBloomFlowers(int[][] flowers, int[] persons) {
        TreeMap map = new TreeMap();
        for(int[] f: flowers){
            int start = f[0];
            int end = f[1] + 1;
            map.put(start, map.getOrDefault(start, 0) + 1);
            map.put(end, map.getOrDefault(end, 0) - 1);
        }
        int pre = 0;
        for(var entry: map.entrySet()){
            map.put(entry.getKey(), entry.getValue() + pre);
            // System.out.println(entry.getKey() + " " + map.get(entry.getKey()));
            pre = entry.getValue();
        }
        int[] keys = new int[map.size()];
        int i = 0;
        for(var k: map.keySet()) keys[i++] = k;
        int[] ans = new int[persons.length];
        i = 0;
        for(var p: persons){
            int key = binarySearch(keys, p);
            if(!map.containsKey(key)) ans[i++] = 0;
            else ans[i++] = map.get(key);
        }
        return ans;
    }
}

你可能感兴趣的:(LeetCode,leetcode,哈希表,二分查找,前缀和)