leetcode 1157. Online Majority Element In Subarray

Implementing the class MajorityChecker, which has the following API:

  • MajorityChecker(int[] arr) constructs an instance of MajorityChecker with the given array arr;
  • int query(int left, int right, int threshold) has arguments such that:
    • 0 <= left <= right < arr.length representing a subarray of arr;
    • 2 * threshold > right - left + 1, ie. the threshold is always a strict majority of the length of the subarray

Each query(...) returns the element in arr[left], arr[left+1], ..., arr[right] that occurs at least threshold times, or -1 if no such element exists.

 

Example:

MajorityChecker majorityChecker = new MajorityChecker([1,1,2,2,1,1]);
majorityChecker.query(0,5,4); // returns 1
majorityChecker.query(0,3,3); // returns -1
majorityChecker.query(2,3,2); // returns 2

 

Constraints:

  • 1 <= arr.length <= 20000
  • 1 <= arr[i] <= 20000
  • For each query, 0 <= left <= right < len(arr)
  • For each query, 2 * threshold > right - left + 1
  • The number of queries is at most 10000

线段树,每个节点 存区间里最多出现的数并且出现次数高于区间总数量的一半,不存在则等于-1。查询时查询在此区间中,每个节点的值作为候选者,二分查找是否符合条件。

class MajorityChecker {
    HashMap<Integer,ArrayList<Integer>> map;
    int[] arr;
    int[] tree;
    public MajorityChecker(int[] arr) {
        this.arr=arr;
        int n=arr.length;
        tree=new int[n<<2];
        map=new HashMap<>();
        for(int i=0;i<arr.length;i++){
            int v=arr[i];
            if(map.get(v)==null){
                map.put(v,new ArrayList<>());
            }
            map.get(v).add(i);
        }
        build(0,n-1,1);
    }
    
    int build(int l,int r,int p){        
        if(l==r){
            tree[p]=arr[l];
            return arr[l];
        }
        int m=(l+r)/2;
        int num1=build(l,m,p<<1);
        int num2=build(m+1,r,(p<<1)+1);
        if(num1!=-1){
            int v=search(num1,r+1)-search(num1,l);
            if(2*v>r-l+1){
                tree[p]=num1;
                return num1;
            }
        }
        if(num2!=-1){
            int v=search(num2,r+1)-search(num2,l);
            if(2*v>r-l+1){
                tree[p]=num2;
                return num2;
            }
        }
        tree[p]=-1;
        return -1;
    }

    int search(int num,int index){
        ArrayList<Integer> list=map.get(num);
        int l=0,r=list.size();
        while(l<r){
            int m=(l+r)/2;
            if(list.get(m)<index){
                l=m+1; 
            }else{
                r=m;
            }
        }
        return l;
    }

    public int query(int s, int e, int threshold) {
        return query(s,e,0,arr.length-1,1,threshold);
    }

    int query(int s,int e,int l,int r,int p,int threshold){
        if(s<=l&&r<=e){
            int num=tree[p];
            if(num!=-1&&search(num,e+1)-search(num,s)>=threshold){
                return num; 
            }
            return -1;
        }
        int m=(l+r)/2;
        if(s<=m){
            int num1=query(s,e,l,m,p<<1,threshold);
            if(num1!=-1) return num1;
            
        }
        if(e>m){
            int num2=query(s,e,m+1,r,(p<<1)+1,threshold);
            if(num2!=-1) return num2;
        }
        return -1;
    }
}

/**
 * Your MajorityChecker object will be instantiated and called as such:
 * MajorityChecker obj = new MajorityChecker(arr);
 * int param_1 = obj.query(left,right,threshold);
 */

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值