二分查找之查找数组中相同的多个元素详解

二分查找之查找数组中相同的多个元素详解

思路分析

  1. 如果数组中有多个相同的元素,而正好要查找这些元素的下标,则应该以集合的形式返回
  2. 二分查找的整体思路不变,还是使用递归查找,若没有找到则返回空集合
  3. 但是当找到一个要查找的元素时,不能直接返回,而是向左或者向右扫描,判断找到的这个元素左侧或者右侧元素也是要查找的值,如果是,则记录其索引,如果不是,则结束查找,直接返回
  4. 源码及详解见下

源码及分析

/**
     * 二分查找,需要保证数组元素有序
     * 二分查找扩展之查找该数组中相同的多个元素,以集合的形式返回
     *
     * @param arr     要查找的原数组
     * @param left    左侧索引
     * @param right   右侧索引
     * @param findVal 要查找的值
     * @return 以集合的形式返回要查找的值
     */
    public static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
        //如果数组查找完还没有找到,直接返回 空集合
        if (left > right) {
            return new ArrayList<>();
        }
        //定义变量保存中间值和中间索引
        int mid = (left + right) / 2;
        int midVal = arr[mid];
        //如果要查找的值在中间值的右边,则向右递归
        if (findVal > midVal) {
            return binarySearch2(arr, mid + 1, right, findVal);
            //如果要查找的值在中间值的左边,则向左递归
        } else if (findVal < midVal) {
            return binarySearch2(arr, left, mid - 1, findVal);
        } else {
            //否则找到要查找的值,向左和向右扫描,查找是否有相同的
            //定义集合保存查找到的元素索引
            List<Integer> list = new ArrayList<>();
            //向左扫描
            int index = mid - 1;
            while (true) {
                if (index < 0 || arr[index] != findVal) {
                    break;
                }
                list.add(index);
                index--;
            }
            list.add(mid);
            //向右扫描
            index = mid + 1;
            while (true) {
                if (index == arr.length || arr[index] != findVal) {
                    break;
                }
                list.add(index);
                index++;
            }
            return list;
        }
    }
posted @ 2021-06-03 22:34  mx_info  阅读(1090)  评论(0)    收藏  举报