首页 > 其他分享 >二分查找法lowerCeil版(找某个重复值的最小下标)利用二分upper法实现

二分查找法lowerCeil版(找某个重复值的最小下标)利用二分upper法实现

时间:2023-06-22 15:14:23浏览次数:41  
标签:二分 upper arr 下标 target index int mid lowerCeil

也是利用二分的upper法实现的,不知道什么是upper?看这里 -> 二分查找法upper版(找大于某个值的最小下标)递归+非递归版 - 翰林猿 - 博客园 (cnblogs.com)

思路

  • 先利用upper找到上界的index

  • 拿着index-1的下标(也就是重复值的最大下标)向前遍历,一直到遍历到发现不相等的元素即可。

package com.Search;
​
/**
 * @Author: 翰林猿
 * @Description: 查找目标元素最小的下标元素 lowerCeil
 **/
public class BinarySearchCeil {
    public BinarySearchCeil() {
    }
​
    public static <E extends Comparable<E>> int searchLowerCeil(E[] data, E target) {
        return lowerCeil(data, target);
    }
​
    public static <E extends Comparable<E>> int searchUpper(E[] data, int l, int r, E target) {
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (data[mid].compareTo(target) == 0) {
                return mid + 1;
            } else if (data[mid].compareTo(target) > 0) { // 这个r = mid是因为mid的位置可能是目标值
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        // l和r最后都都指向同一个位置。没找到则返回arr.length
        return l;
    }
​
    public static <E extends Comparable<E>> int lowerCeil(E[] arr, E target) {   //查找最小下标
        int minIndex = 0;
        int index = searchUpper(arr, 0, arr.length, target);                     //也是先用upper获取最大下标先
        if (arr[index - 1].compareTo(target) == 0) {                             //如果最大下标-1等于目标值,说明其实是上界
            minIndex = findMinIndex(arr, index - 1);                             //找到最小下标
        }
        return minIndex;
    }
​
    public static <E extends Comparable<E>> int findMinIndex(E[] arr, int index) {
        int r = index;
        while (arr[index] == arr[r]) {      //不断向前遍历直到发现与target不同的元素下标
            if (r == 0)
                return 0;
            else
                r--;
        }
        return r + 1;                       //最后while循环过后的r是最小target的前一个下标,所以要+1,返回target最小的下标
    }
​
    public static void main(String[] args) {
        Integer[] arr = {1, 1, 1, 2, 2, 3, 6, 6, 6 , 8, 18, 20};
        int lowerCeil = searchLowerCeil(arr, 20);
        System.out.println(lowerCeil);
    }
}

标签:二分,upper,arr,下标,target,index,int,mid,lowerCeil
From: https://www.cnblogs.com/hanlinyuan/p/17497749.html

相关文章

  • 二分查找法ceil版(找某个重复值的最大下标)利用二分upper法实现
    如果有等于target的元素就返回最大的下标元素。如果没有等于target的元素,那么就返回大于target的最小元素,即这一篇文章实现的upper函数。二分查找法upper版(找大于某个值的最小下标)递归+非递归版-翰林猿-博客园(cnblogs.com),当然你们也可以更改返回值-1什么的作为查找......
  • 二分查找法upper版(找大于某个值的最小下标)递归+非递归版
    需求:比如说查询一个班级大于60分的最低分等等。思路与二分法基本相同,只不过是对比的逻辑发生了一些小变化,这里所说的上界就是指大于某个值的最小下标。当mid<target:说明target的上界还在mid的右边,所以要去找比mid大的当mid>target:说明mid有可能是target的上界,所以......
  • 基础算法:二分,贪心等 学习笔记
    普及组基础算法这些都是零零散散接触过的基础算法,写个笔记把这些整理到一起来。线性降维技巧之前在学校洛谷团队里看到一个题单,觉得这些技巧可能有用,就转存了。前缀和差分前缀和是一种对区间求和问题进行降维的方法。具体地,对于给定数组\(A[n]\),求出\(A[l,r]\)区间和这个......
  • transform (牛客多校) (双指针+二分+ 中位数妙用+前缀和相减维护)
    题目大意:n个商店在一条直线上, 有一个xi然后有ai个商品你可以把商店的物品移动到另一个商店,代价为:abs(xi-xj)在代价不超过T的情况下你可以选择一个商店来让其他商店的物品都移到这个商店,问最多移动多少个物品  思路:双指针维护一个最大的区间,因......
  • Luogu3168 [CQOI2015] 任务查询系统 - 主席树 - 二分 -
    题目链接:https://www.luogu.com.cn/problem/P3168题解:主席树可以解决一类j静态区间第\(k\)小的问题,我们先来看看这是怎么工作的主席树的本质就是有很多棵线段树,然后发现这些线段树绝大多数都是重叠的,因此可以优化到空间复杂度\(O(n\logn)\)在这里,我们将序列的每一个位置......
  • Primes on Interval(欧拉筛+二分+滑动窗口)
    【题面】你决定用素数定理来做一个调查.众所周知,素数又被称为质数,其含义就是除了数字一和本身之外不能被其他任何的数字除尽.现在给定一个正整数序列 ,+1,⋯ ,a,a+1,⋯,b (≤)(a≤b),请找出一个最小值 l,使其满足对于任意一个长度为 l 的子串,都包含 k 个质数.......
  • Best Cow Fences(前缀和+特殊二分)
    之前的二分大多数都是整数类型的,今天又学到一种新型的二分,浮点数的二分,浮点数的二分可太巧妙了.且听我细细分说::OpenJudge-2018:BestCowFences#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+10;intn,k;doublea[N],s[N],l,r;boolcheck(doubleu)......
  • 和与积 题解 简单二分查找
    题目大意:给定两个整数\(a(2\lea\le2\times10^9)\)和\(b(1\leb\le10^{18})\)。判断是否存在两个正整数\(x\)和\(y\),同时满足如下两个条件:\(x+y=a\)\(x\timesy=b\)解题思路:用\(a-x\)表示\(y\),可以得到面积的表达式为\(x\times(a-x)\),然后可以发现......
  • 整体二分学习笔记
    概念对于一个很多询问的题,假如对于一个询问可以二分处理,同时一次check可以只用\(n\)的时间处理所有询问的check结果,我们可以使用整体二分来做这个题。思想设函数\(\operatorname{solve}(S,L,R)\)为现在正在处理询问序列\(S\)里的询问,答案值域为\([L,R]\)。向下......
  • 二分答案
    概述二分答案即利用二分查找来得到答案,一般情况下,左边界$left$是$0$或者$1$;右边界$right$则视题目条件而定,取一个很大的数,然后利用二分查找的思想,来找到答案。二分答案的要求如果题目能够使用二分答案的思想来解决,那么$[left,right]$范围内,要满足二段性,即对$[left,......