二分法

/**
 * 二分法:每次把数组拆成两份
 *  1、查询有序数组中的指定值的位置
 *  2、查询有序数组中大于等于某个值的最左侧的位置
 *  3、查找局部最小值
 *      局部最小:乱序数组中,相邻的数不相等,某个值和它相邻的值比较,如果最小,就是局部最小
 */
public class DichotomyTest {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,6,8,11,15,17};
        findNum(arr, 3);
        int[] arr2 = {1,2,2,2,3,3,3,4,4,4,6,8,11,15,17};
        findNum(arr2, 4);
        int[] arr3 = {12,6,3,6,12,8,20,23,19,5,100};
        findSmall(arr3);
    }

    /**
     * 二分法找有序数组中的某个值的位置
     */
    public static void findNum(int[] arr, int num) {
        if (arr == null || arr.length == 0) {
            return;
        }
        int start = 0;
        int end = arr.length - 1;
        int mid = start + ((end - start) >> 2);
        while (arr[mid] != num) {
            if (arr[mid] < num) {
                start = mid;
            } else {
                end = mid;
            }
            mid = (start + end)/2;
        }
        System.out.println(mid);
    }

    /**
     * 二分法找有序数组中满足大于等于某个值的最左侧的位置
     */
    public static void findLeftNum(int[] arr, int num) {
        if (arr == null || arr.length == 0) {
            return;
        }
        int start = 0;
        int end = arr.length - 1;
        int mid = (arr.length - 1)/2;
        do {
            if (arr[mid] < num) {
                start = mid;
            } else {
                end = mid;
            }
            mid = (start + end) / 2;
        } while (mid != start);
        System.out.println(mid);
    }

    /**
     * 二分法查找局部最小值
     * 局部最小:乱序数组中,相邻的数不相等,某个值和它相邻的值比较,如果最小,就是局部最小
     */
    public static void findSmall(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        if (arr.length == 1){
            System.out.println(arr[0]);
        }
        if (arr[0] < arr[1]) {
            System.out.println(arr[0]);
        }
        if (arr[arr.length - 1] < arr[arr.length - 2]) {
            System.out.println(arr[arr.length - 1]);
        }
        int start = 0;
        int end = arr.length - 1;
        int mid = (arr.length - 1)/2;

        while (true) {
            if (arr[mid-1] > arr[mid] && arr[mid + 1] > arr[mid]) {
                System.out.println(arr[mid]);
                return;
            } else if (arr[mid - 1] < arr[mid]) {
                end = mid;
            } else {
                start = mid;
            }
            mid = (start + end)/2;
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容