leetcode 1287: 有序数组出现次数超过25%的元素(神烦二分查找上下界)

题解

  • 题意:给定非递减整数数组arr, arr中恰好有一个整数,它的出现次数超过数组元素总数的 25%。
  • 题解:最简单的就是利用双指针设置一个0.25*arr.length大小的窗口,一位位往后遍历,这个几行代码就可以实现,O(n)
    • 我们再看看题目,题目告诉我们,数组是排好序的,既然是因为数组是排好序的,就可以考虑二分法计数法。二分法计数是因为二分查找有两种,一种是找到重复数字第一次出现的位置,另一种是找到重复数据最后一次出现的位置,这也成为lower_boundupper_bound查找法。
    • 这题如何套用二分计数呢,最直观的做法就是从前往后,对数组每个元素都进行二分计数,可是这种做法就是O(nlogn)的复杂度,反而增加了,那有什么更好的做法吗
    • 再考虑一下,上面的做法其实多了很多没有必要的计算,因为大多元素出现的次数都是小于要求频率的,这就可以在遍历数据的时候进行筛选
    • 我们可以考虑将遍历的跨度设置为0.25*arr.length,因为如果数据大于0.25*arr.length次,一次循环跳动是不会筛除这个元素的,反之则可能会被删除,因此减少了大量没必要的运算,最后最多只需要进行4次二分查找,因此复杂度是O(logn)
  • 实现:想法很简单,实现很恶心,要注意很多鸡毛蒜皮的边界条件
    public int binarysearch(int[]arr, int target){
        int l = 0;
        int r = arr.length-1;
        int s = 0;
        int cnt = 0;
        
        while(l<r){
            int mid = (l+r+1)>>1;
            if(arr[mid] <= target) l = mid;
            else r = mid-1;
        } 
        int posr = l;
        l = 0;
        r = arr.length-1;
        while(l<r){
            int mid = (l+r)>>1;
            if(arr[mid] >= target) r = mid;
            else l = mid+1;
        }
        int posl = r; 
        return posr-posl+1;
    }
    public int findSpecialInteger(int[] arr) {
        int n = arr.length; 
        int quart = n/4+1;
        int num = 0;
        int j = 0;
        while(j < n){ 
            if(binarysearch(arr, arr[j]) >= quart) return arr[j];
            j+=quart;
        }
        return num;
    }

题目

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值