【二分查找专题】给出四种二分查找的模板

本问题对应课程链接:剑指offer刷题第五期

本次打卡的任务很简单,就是给出四种变形二分查找的模版代码,并且给出了对应的方法名字。

比如对于一个有序数组

arr = [1,2,3,3,3,4,5,5,7],target = 3,那么

1.寻找第一个大于 target 的元素的下标,本案例中4 就是第一个大于 target 的元素 ,下标 = 5。
对应方法名格式为
int upper(int[] arr, int target){

//如果都不存在,则返回-1
}

2.如果数组中存在元素等于 target,则返回最后一个等于target 的元素下标,如果不存在,则返回第一个大于 target 的元素下标。本案例中最后一个等于target的下标 = 4。
对应方法名
int floor_upper(int[] arr, int target){
//如果都不存在,则返回-1
}

3.寻找最后一个小于 target 的元素的下标,本案例中 2 则是最后一个小于 target 的,下标 = 1.
对应方法名格式为
int lower(int[] arr, int target){

//如果都不存在,则返回-1
}

4.如果数组中存在元素等于 target,则返回第一个等于target 的下标,如果不存在,则返回最后一个小于 target 的元素的下标。本案例中第一个等于target的下标 = 2。
对应方法名格式为
int floor_lower(int[] arr, int target){

//如果都不存在,则返回-1
}

注意:大家给了模版之后,选择一个适合自己的模版,以后都用这个模版,忘了怎么办?这玩意的区别就是要么是大于,要么是大于等于,你如果记混了,可以随便找一组数据试一下,就能分辨出来了,我笔试时都这样干,,,

答案来了,具体答案看这篇文章:4种二分查找模版讲解

共以下 9 个回答

  • 黎明之前 普通 2023年9月25日 上午9:34

    //给出四种变形二分查找的模板代码
    //有序数组 arr = [1,2,3,3,3,4,5,5,7]
    //target = 3

    //给出四种变形二分查找的模板代码
    //有序数组 arr = [1,2,3,3,3,4,5,5,7]
    //target = 3

    //寻找第一个大于target 的元素的下标,本案例中 4就是第一个大于target 的元素,下标 = 5
    int upper(int[] arr, int target) {
    //如果都不存在,则返回-1
    if(arr[arr.length-1] <= target) return -1;

    int l = 0;
    int r = arr.length - 1;
    int mid = -1;
    while(l < r) {
        mid = (l + r) / 2;
        if(arr[mid] > target) {
            r = mid;//这里不能减一,否则mid是第一个大于target 的元素,的场景就缺失了
        }
        else if(arr[mid] < target) {
            l = mid + 1;
        }
        else {//arr[mid] = target
            l = mid + 1;
        }
    }
    //l就是第一个大于target 的元素的下标
    return l;
    

    }

    //如果数组中存在元素等于target,则返回最后一个等于target的元素的下标,
    //如果不存在,则返回第一个大于target的元素的下标。本案例中最后一个等于target的下标 = 4
    int floor_upper(int[] arr, int target) {
    //如果都不存在,则返回-1
    if(arr[arr.length-1] < target) return -1;
    if(arr[arr.length-1] target) return arr.length-1;

    int l = 0;
    int r = arr.length - 1;
    int mid = -1;
    while(l < r) {
        mid = (l + r) / 2;
        if(arr[mid] > target) {
            r = mid;//这里不能减一,否则mid是第一个大于target 的元素,的场景就缺失了
        }
        else if(arr[mid] < target) {
            l= mid + 1;
        }
        else {//arr[mid] = target
            l = mid + 1;
        }
    }
    //l就是第一个大于target 的元素的下标,如果存在等于target的元素,一定是l-1
    if(l - 1 >= 0 && arr[l - 1] == target) {
        return l - 1; 
    }
    return l;
    

    }

    //寻找最后一个小于target的元素的下标,本案例中2则是最后一个小于target的,下标1
    int lower(int[] arr, int target) {
    //如果都不存在,则返回-1
    if(arr[0] >= target) return -1;

    int l = 0;
    int r = arr.length - 1;
    int mid = -1;
    while(l < r) {
        mid = (l + r + 1) / 2;//虽然明白有一个场景需要做向上取整,但是说不清楚其中的原理
        if(arr[mid] > target) {
            r = mid -1;
        }
        else if(arr[mid] < target) {
            l = mid;
        }
        else {//arr[mid] = target
            r = mid - 1;
        }
    }
    //l就是第一个小于target 的元素的下标
    return l;
    

    }

    //如果数组中存在元素等于target,则返回第一个等于target的下标,
    //如果不存在,则返回最后一个小于target的元素的下标
    int floor_lower(int[] arr, int target) {
    //如果都不存在,则返回-1
    if(arr[0] > target) return -1;
    if(arr[0] target) return 0;

    int l = 0;
    int r = arr.length - 1;
    int mid = -1;
    while(l < r) {
        mid = (l + r + 1) / 2;//虽然明白有一个场景需要做向上取整,但是说不清楚其中的原理
        if(arr[mid] > target) {
            r = mid -1;
        }
        else if(arr[mid] < target) {
            l = mid;
        }
        else {//arr[mid] = target
            r = mid - 1;
        }
    }
    if(l + 1 < arr.length && arr[l + 1] == target) {
        return l + 1;//l就是第一个小于target 的元素的下标,如果存在等于target的元素,一定是l+1
    }
    //l就是第一个小于target 的元素的下标
    return l;
    

    }

    //简单记录一下寻找
    //第一个大于target的元素的下标为什么向下取整(除法默认的)
    //最后一个小于target的元素的下标为什么向上取整?mid = (l + r + 1) / 2;

    第一个大于target的元素,第一次使用二分查找时,如果Mid对应的元素正好是最后一个等于target的元素,那么下一个寻找区间是[Mid+1, right]。区间里都是大于target的元素
    即mid+1就是第一个大于target的元素。mid = (l + r) / 2可以取到左边界。
    第一个大于target的元素 这个要求就是 左边界的值

    最后一个小于target的元素的下标,第一次使用二分查找时,如果Mid对应的元素正好是第一个等于target的元素, 那么下一个寻找区间是[left, mid-1],区间里都是小于target的元素
    即mid-1就是第一个大于target的元素。mid = (l + r) / 2永远只能取到左边界的值, 而mid = (l + r + 1) / 2才可以取到右边界。
    最后一个小于target的元素 这个要求就是 右边界的值,所以需要向上取整

    0 赞同 0 条回复
  • sc_Yang 普通 2023年9月2日 下午5:30

    // 对有序数列进行二分查找,判断当前区间的时候两侧是闭区间的,意思是在当前的轮次当中,两侧的端点元素都加进考虑
    // 寻找第一个大于target的元素下标

    // 对有序数列进行二分查找,判断当前区间的时候两侧是闭区间的,意思是两侧的端点元素都加进考虑
    // 寻找第一个大于target的元素下标
    int func1(vector arr, int target){
        int n = arr.size();
        // 如果最后一位都小于等于目标值,则表示该序列中没有所求
        if(arr[n-1] <= target) return -1;
        int l,=0, r = n-1;
        while(l arr, int target){
        int n = arr.size();
        if(arr[n-1] arr, int target){
        int n = arr.size();
        if(arr[n-1] arr, int target){
        int n = arr.size();
        if(arr[n-1]=0 && arr[cur]==target) cur--;
                return cur+1;
            }
            else{
                r = m-1;
            }
        }
        return l;
    }
    
    0 赞同 0 条回复
  • Sheng 永久会员 2023年9月1日 下午4:46
    //给出四种变形二分查找的模板代码
    //有序数组 arr = [1,2,3,3,3,4,5,5,7]
    //target = 3
    
    //给出四种变形二分查找的模板代码
    //有序数组 arr = [1,2,3,3,3,4,5,5,7]
    //target = 3
    
    //寻找第一个大于target 的元素的下标,本案例中 4就是第一个大于target 的元素,下标 = 5 
    int upper(int[] arr, int target) {
        //如果都不存在,则返回-1
        if(arr[arr.length-1] <= target) return -1;
        
        int l = 0;
        int r = arr.length - 1;
        int mid = -1;
        while(l < r) {
            mid = (l + r) / 2;
            if(arr[mid] > target) {
                r = mid;//这里不能减一,否则mid是第一个大于target 的元素,的场景就缺失了
            }
            else if(arr[mid] < target) {
                l = mid + 1;
            }
            else {//arr[mid] = target
                l = mid + 1;
            }
        }
        //l就是第一个大于target 的元素的下标
        return l;
    }
    
    
    //如果数组中存在元素等于target,则返回最后一个等于target的元素的下标,
    //如果不存在,则返回第一个大于target的元素的下标。本案例中最后一个等于target的下标 = 4
    int floor_upper(int[] arr, int target) {
        //如果都不存在,则返回-1
        if(arr[arr.length-1] < target) return -1;
        if(arr[arr.length-1] == target) return arr.length-1;
        
        int l = 0;
        int r = arr.length - 1;
        int mid = -1;
        while(l < r) {
            mid = (l + r) / 2;
            if(arr[mid] > target) {
                r = mid;//这里不能减一,否则mid是第一个大于target 的元素,的场景就缺失了
            }
            else if(arr[mid] < target) {
                l= mid + 1;
            }
            else {//arr[mid] = target
                l = mid + 1;
            }
        }
        //l就是第一个大于target 的元素的下标,如果存在等于target的元素,一定是l-1
        if(l - 1 >= 0 && arr[l - 1] == target) {
            return l - 1; 
        }
        return l;
    }
    
    //寻找最后一个小于target的元素的下标,本案例中2则是最后一个小于target的,下标1
    int lower(int[] arr, int target) {
        //如果都不存在,则返回-1
        if(arr[0] >= target) return -1;
        
        int l = 0;
        int r = arr.length - 1;
        int mid = -1;
        while(l < r) {
            mid = (l + r + 1) / 2;//虽然明白有一个场景需要做向上取整,但是说不清楚其中的原理
            if(arr[mid] > target) {
                r = mid -1;
            }
            else if(arr[mid] < target) {
                l = mid;
            }
            else {//arr[mid] = target
                r = mid - 1;
            }
        }
        //l就是第一个小于target 的元素的下标
        return l;
    
    }
    
    //如果数组中存在元素等于target,则返回第一个等于target的下标,
    //如果不存在,则返回最后一个小于target的元素的下标
    int floor_lower(int[] arr, int target) {
        //如果都不存在,则返回-1
        if(arr[0] > target) return -1;
        if(arr[0] == target) return 0;
        
        int l = 0;
        int r = arr.length - 1;
        int mid = -1;
        while(l < r) {
            mid = (l + r + 1) / 2;//虽然明白有一个场景需要做向上取整,但是说不清楚其中的原理
            if(arr[mid] > target) {
                r = mid -1;
            }
            else if(arr[mid] < target) {
                l = mid;
            }
            else {//arr[mid] = target
                r = mid - 1;
            }
        }
        if(l + 1 < arr.length && arr[l + 1] == target) {
            return l + 1;//l就是第一个小于target 的元素的下标,如果存在等于target的元素,一定是l+1
        }
        //l就是第一个小于target 的元素的下标
        return l;
    }
    
    //简单记录一下寻找   
    //第一个大于target的元素的下标为什么向下取整(除法默认的)
    //最后一个小于target的元素的下标为什么向上取整?mid = (l + r + 1) / 2;
    
    第一个大于target的元素,第一次使用二分查找时,如果Mid对应的元素正好是最后一个等于target的元素,那么下一个寻找区间是[Mid+1, right]。区间里都是大于target的元素
    即mid+1就是第一个大于target的元素。mid = (l + r) / 2可以取到左边界。
    第一个大于target的元素   这个要求就是 左边界的值
    
    最后一个小于target的元素的下标,第一次使用二分查找时,如果Mid对应的元素正好是第一个等于target的元素, 那么下一个寻找区间是[left, mid-1],区间里都是小于target的元素
    即mid-1就是第一个大于target的元素。mid = (l + r) / 2永远只能取到左边界的值, 而mid = (l + r + 1) / 2才可以取到右边界。
    最后一个小于target的元素    这个要求就是  右边界的值,所以需要向上取整
    
    0 赞同 0 条回复
  • sincere 普通 2023年8月31日 下午1:57
    • 思路:选用左闭右开区间,用临时变量ans记录目标下标值,关于边界值的判断还需要记一下
    
        @Test
        public void test() {
            int[] ints = {1, 2, 2, 4, 4, 5, 5, 7};
            int target = 9;
            int upper = upper(ints, target);
            System.out.println("第一个大于target 的下标:" + upper);
            int upper1 = floor_upper(ints, target);
            System.out.println("最后一个等于target|第一个大于target 的下标:" + upper1);
            int lower = lower(ints, target);
            System.out.println("最后一个小于target 的下标:" + lower);
            int lower1 = floor_lower(ints, target);
            System.out.println("最后一个小于target|第一个等于target 的下标:" + lower1);
        }
    
        // 寻找第一个大于target的元素下标
        public int upper(int[] arr, int target) {
            int left = 0;
            int right = arr.length;
            int ans = -1;
            while (left < right) {
                int mid = (right - left) / 2 + left;
                if (arr[mid] <= target) {
                    left = mid + 1;
                } else {
                    right = mid;
                    ans = right;
                }
            }
            return ans;
        }
    
        // 寻找最后一个等于target的元素下标,不存在则返回第一个大于target的
        public int floor_upper(int[] arr, int target) {
            int left = 0;
            int right = arr.length;
            int ans = -1;
            while (left < right) {
                int mid = (right - left) / 2 + left;
                if (arr[mid] == target) {
                    ans = mid;
                    left = mid + 1;
                } else if (arr[mid] < target) {
                    left = mid + 1;
                } else {
                    right = mid;
                    ans = mid;
                }
            }
            return ans;
        }
    
        // 寻找最后一个小于target的
        public int lower(int[] arr, int target) {
            int left = 0;
            int right = arr.length;
            int ans = -1;
            while (left < right) {
                int mid = (right - left) / 2 + left;
                if (arr[mid] < target) {
                    left = mid + 1;
                    ans = mid + 1;
                } else {
                    right = mid;
                }
            }
            return ans;
        }
    
        // 寻找第一个等于target的,不存在则返回最后一个小于target的
        public int floor_lower(int[] arr, int target) {
            int left = 0;
            int right = arr.length;
            int ans = -1;
            while (left < right) {
                int mid = (right - left) / 2 + left;
                if (arr[mid] == target) {
                    right = mid;
                    ans = mid;
                } else if (arr[mid] < target) {
                    left = mid + 1;
                    ans = mid;
                } else {
                    right = mid;
                }
            }
            return ans;
        }
    
    0 赞同 0 条回复
  • 帝心引力 永久会员 2023年8月27日 下午9:55
    int func1(vector<int> arr, int target){
        int n = arr.size();
        if(arr[n-1] <= target) return -1;
        int l = 0, r = n-1;
        while(l < r){    // 如果写成 l <= r, 在这个例子中会变成死循环
            int m = l + (r-l)/2;
            if(arr[m] <= target) l = m+1;
            else r = m;
        }
        return l;
    }
    int func2(vector<int> arr, int target){
        int n = arr.size();
        if(arr[n-1] < target) return -1;
        int l = 0, r = n-1;
        while(l < r){  // 若写成 l<=r 也会成为死循环
            int m = l + (r-l)/2;
            if(arr[m] < target) l = m+1;
            else if(arr[m] == target){  // 如果相等,向右扩展
                int cur = m;
                while(cur<n && arr[cur] == target) cur++;
                return cur-1;
            }
            else r = m;
        }
        return l;
    }
    int func3(vector<int> arr, int target){
        int n = arr.size();
        if(arr[0] >= target) return -1;
        int l = 0, r = n-1;
        while(l < r){
            int m = l + (r-l)/2;
            if(arr[m] >= target) r = m-1;
            else l = m;
        }
        return l;
    }
    int func4(vector<int> arr, int target){
        int n = arr.size();
        if(arr[0] > target) return -1;
        int l = 0, r = n-1;
        while(l < r){
            int m = l + (r-l)/2;
            if(arr[m] > target) r = m-1;
            else if(arr[m] == target){  // 如果相等,向左扩展
                int cur = m - 1;
                while(cur>=0 && arr[cur] == target) cur--;
                return cur+1;
            }
            else l = m;
        }
        return l;
    }
    
    0 赞同 0 条回复
  • 塔底的仰望 永久会员 2023年8月26日 下午2:05
    public class BinarySearch {
        //寻找第一个大于target的元素的下标
        public int upper(int[] arr, int target) {
            //先判断特殊情况
            if (arr == null || arr.length == 0) {
                return -1;
            }
            int l = 0;
            int r = arr.length - 1;
            if (arr[r] <= target) {
                return -1;
            }
            while (l < r) {
                int mid = (r - l) / 2 + l;
                if (arr[mid] > target) {
                    r = mid;
                } else { // arr[mid] <= target
                    l = mid + 1;
                }
            }
            return l;
        }
    
        // 若数组存在元素等于target,则返回最后一个等于target的元素下标
        // 若不存在则返回,第一个大于target的元素下标
        public int floor_upper(int[] arr, int target) {
            //先判断特殊情况
            if (arr == null || arr.length == 0) {
                return -1;
            }
            int l = 0;
            int r = arr.length - 1;
            if (arr[r] < target) {
                return -1;
            }
            while (l < r) {
                int mid = (r - l) / 2 + l;
                if (arr[mid] > target) {
                    r = mid;
                } else { // arr[mid] <= target
                    l = mid + 1;
                }
            }
            if (l - 1 >= 0 && arr[l - 1] == target) {
                l = l - 1;
            }
            return l;
        }
    
        //寻找最后一个小于target的元素下标
        public int lower(int[] arr, int target) {
            //先判断特殊情况
            if (arr == null || arr.length == 0 || arr[0] >= target) {
                return -1;
            }
            int l = 0;
            int r = arr.length - 1;
            if (arr[l] >= target) {
                return -1;
            }
            while (l + 1< r) {
                int mid = (r - l) / 2 + l;
                if (arr[mid] >= target) {
                    r = mid - 1;
                } else { // arr[mid] < target
                    l = mid;
                }
            }
            return l;
        }
    
        // 若数组存在元素等于target,则返回第一个等于target的元素下标
        // 若不存在,则返回最后一个小于target的元素的下标
        public int floor_lower(int[] arr, int target) {
            //先判断特殊情况
            if (arr == null || arr.length == 0 || arr[0] > target) {
                return -1;
            }
            int l = 0;
            int r = arr.length - 1;
            while (l < r) {
                int mid = (r - l) / 2 + l;
                if (arr[mid] >= target) {
                    r = mid - 1;
                } else { // arr[mid] < target
                    l = mid;
                }
            }
            if (l + 1 < arr.length && arr[l + 1] == target) {
                l = l + 1;
            }
            return l;
    
        }
    
        public static void main(String[] args) {
            int[] arr = new int[]{1, 2,3,3,3,4,5,5,7};
            int target = 3;
            BinarySearch b = new BinarySearch();
            int index = b.floor_upper(arr, target);
            System.out.println("index = "+ index + ", value = " + arr[index]);
        }
    
    }
    
    0 赞同 0 条回复
  • 别扒拉我 普通 2023年8月25日 下午11:12

    对于小于或小于等于类的问题,必须对mid取上限,以收缩左边界;对于大于或大于等于类的问题,直接对mid取下限即可,自动收缩右边界。

    class Solution {
    
        public int upper(int[] arr, int target){
            int l = 0;
            int r = arr.length - 1;
            if(arr[r] <= target){
                return -1;
            }
            while(l < r){
                int mid = (r - l) / 2 + l;
                if(arr[mid] > target){
                    r = mid;
                } else if(arr[mid] == target){
                    l = mid + 1;
                }else {
                    l = mid + 1;
                }
            }
            return l;
        }
    
        public int floor_upper(int[] arr, int target){
            int l = 0;
            int r = arr.length - 1;
            if(arr[r] < target){
                return -1;
            }
            while(l < r){
                int mid = (r - l) / 2 + l;
                if(arr[mid] > target){
                    r = mid;
                } else if(arr[mid] == target){
                    l = mid + 1;
                }else {
                    l = mid + 1;
                }
            }
    
            if(l - 1 >= 0 && arr[l - 1] == target){
                return l -1;
            }
    
            return l;
        }
    
        public int lower(int[] arr, int target){
            int l = 0;
            int r = arr.length - 1;
            if(arr[l] >= target){
                return -1;
            }
            while(l < r){
                int mid = (r - l + 1) / 2 + l;
                if(arr[mid] > target){
                    r = mid - 1;
                } else if(arr[mid] == target){
                    r = mid - 1;
                }else {
                    l = mid;
                }
            }
            return l;
        }
    
    
        public int floor_lower(int[] arr, int target){
            int l = 0;
            int r = arr.length - 1;
            if(arr[l] > target){
                return -1;
            }
            while(l < r){
                int mid = (r - l + 1) / 2 + l;
                if(arr[mid] > target){
                    r = mid - 1;
                } else if(arr[mid] == target){
                    r = mid - 1;
                }else {
                    l = mid;
                }
            }
            if(l + 1 < arr.length && arr[l + 1] == target){
                return l + 1;
            }
            return l;
        }
    }
    
    0 赞同 0 条回复
  • 行动派小彩笔 普通 2023年8月25日 下午10:30
    // 新的思想,红蓝边界
    int upper(vector<int>& nums, int target)
    {
        /*
        vector<int> nums{1,2,3,3,3,4,5,5,7 };
        int target = 3;
        */
        // 1. 找一个大于target的元素的下标
        int left = -1;
        int right = nums.size();
        while (left + 1 != right)
        {
            int mid = (left + right) / 2;
            if (nums[mid]>target) right = mid;
            else left = mid;
        }
    
        return right;
    }
    
    int equal_upper(vector<int>& nums, int target)
    {
        /*
       vector<int> nums{1,2,3,3,3,4,5,5,7 };
       int target = 3;
       */
        // 2.查找数组等于target的元素,存在返回下标,不存在返回第一个大于target元素的下标
        int left = -1;
        int right = nums.size();
        while (left+1!=right)
        {
            int mid = (left + right) / 2;
            if (nums[mid]>target) right = mid;
            else left = mid;
        }
        return nums[right - 1] == target ? left : right;
    }
    
    int lower(vector<int>& nums, int target) // 3.寻找最后一个小于target的元素的下标
    {
        /*
         vector<int> nums{1,2,3,3,3,4,5,5,7 };
         int target = 3;
         */
        int left = -1;
        int right = nums.size();
        while (left + 1 != right)
        {
            int mid = (left + right) / 2;
            if (nums[mid]<target) left = mid;
            else right = mid;
        }
        return left;
    }
    //查找数组中等于target元素,存在返回下标,不存在返回最后一个小于target元素的下标
    int equel_lower(vector<int>& nums, int target) 
    {
        /*
         vector<int> nums{1,2,3,3,3,4,5,5,7 };
         int target = 3;
         */
        int left = -1;
        int right = nums.size();
        while (left + 1 != right)
        {
            int mid = (left + right) / 2;
            if (nums[mid]<target) left = mid;
            else right = mid;
        }
        return nums[left + 1] == target ? right : left;
    }
    
    
    int main()
    {
        int num;
        vector<int> nums{ 1,2,3,3,3,4,5,5,7 };
        int target = 3;
        // 1. 找一个大于target的元素的下标
        cout << upper(nums, target) << endl;
        // 2.查找数组等于target的元素,存在返回下标,不存在返回第一个大于target元素的下标
        cout << equal_upper(nums, target) << endl;
        // 3.寻找最后一个小于target的元素的下标
        cout << lower(nums, target) << endl;
        // 4.查找数组中等于target元素,存在返回下标,不存在返回最后一个小于target元素的下标
        cout << equel_lower(nums, target) << endl;
    
        return 0;
    }
    
    0 赞同 0 条回复
  • c 普通 2023年8月25日 下午10:30

    lower和upper注意偶数时中间点取偏左还是偏右

    public static int upper(int[] arr, int target){
            if (arr.length==0 || arr[arr.length-1]<=target){
                return -1;
            }
            int l =0;
            int r =arr.length-1;
            int mid;
            while (l<r){
                mid=l+((r-l)>>1);
                if (arr[mid]>target){
                    r=mid;
                } else {
                    l=mid+1;
                }
            }
            return l;
        }
        public static int floor_upper(int[] arr, int target){
            if (arr.length==0 || arr[arr.length-1]<target){
                return -1;
            }
            int l =0;
            int r =arr.length-1;
            int mid;
            while (l<r){
                mid=l+((r-l)>>1);
                if (arr[mid]>target){
                    r=mid;
                } else {
                    l=mid+1;
                }
            }
            if (l-1>=0&&arr[l-1]==target){
                return l-1;
            }
            return l;
        }
    
        public  static int lower(int[] arr, int target){
            if (arr.length==0 || arr[0]>=target){
                return -1;
            }
            int l =0;
            int r =arr.length-1;
            int mid;
            while (l+1<r){
                mid=l+((r-l+1)>>1);
                if (arr[mid]>=target){
                    r=mid-1;
                } else {
                    l=mid;
                }
            }
            return l;
        }
        public static int floor_lower(int[] arr, int target){
            if (arr.length==0 || arr[0]>=target){
                return -1;
            }
            int l =0;
            int r =arr.length-1;
            int mid;
            while (l+1<r){
                mid=l+((r-l+1)>>1);
                if (arr[mid]>=target){
                    r=mid-1;
                } else {
                    l=mid;
                }
            }
    
            if(l + 1 < arr.length && arr[l + 1] == target){
                return l + 1;
            }
            return l;
        }
    
    0 赞同 0 条回复

# 回答此问题

后才能回答