代码-求局部最小值

61 阅读1分钟
package class01.question01;

/**
 * @author ThugsInSuits
 * Date 2024/10/26 06:50
 * Version 1.0
 * @ClassName BiLocalMinimum
 * @Description 求局部最小值
 * 这个问题也证明了一点,使用二分不一定要有序
 **/
public class BiLocalMinimum {
    public static int biLocalMinimum(int[] arr) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
        // base case 数组两侧的情况
        if (arr.length == 1 || arr[0] < arr[1]) {
            return 0;
        }
        if (arr[arr.length - 1] < arr[arr.length - 2] ) {
            return arr.length - 1;
        }

        int left = 1;
        int right = arr.length - 2;
        while(left < right) {
            int mid = left + ((right - left) >>1 );
            // 如果mid>左边的值,那么最小值左边肯定有,所以去左边找
            if (arr[mid] > arr[mid - 1] ) {
                right = mid - 1;
            } else if (arr[mid] > arr[mid + 1]) {
                // 同理,mid>右边的值,那么最小值右边肯定有,抛弃左边,去右边
                left = mid + 1;
            }else {
                // mid 比左右都小,那就是局部最小值了
                return mid;
            }
        }
        return left;
    }

    // 验证求道的局部最小是否正确
    public static boolean isRight(int[] arr,int index) {
        if (arr.length <= 1) {
            return true;
        }

        if (index == 0) {
            return arr[index] < arr[index + 1];
        }
        if (index == arr.length - 1) {
            return arr[index] < arr[index-1];
        }
        return arr[index] < arr[index + 1] && arr[index] < arr[index - 1];
    }


    public static int[] generateRandomArray(int maxSize,int maxValue) {
        int[] arr = new int[(int) (Math.random() * maxSize) + 1];
        arr[0] = (int) (Math.random() * maxValue) -  (int) (Math.random() * maxValue);
        for (int i = 1;i < arr.length;i++) {
            do {
                arr[i] = (int) (Math.random() * maxValue) -  (int) (Math.random() * maxValue);
            }while (arr[i] == arr[i-1]);
        }
        return arr;
    }

    public static void printArray(int[] arr) {
        for (int i : arr) {
            System.out.print(i + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int maxSize = 100;
        int masValue = 100;
        int testTime = 10000;
        for (int i = 0; i < testTime; i++) {
            int[] arr = generateRandomArray(maxSize, masValue);
            int localMinimumIndex = biLocalMinimum(arr);
            if (!isRight(arr,localMinimumIndex)) {
                printArray(arr);
                System.out.println("fail");
                return;
            }
        }
        System.out.printf("success");
    }
}