循环有序数组中查找指定元素

这道题目是我在快看漫画面试时的一道算法题:http://www.cnblogs.com/optor/p/8570548.html
当时现场并未写出解答来,现在有些后悔,其实就是在二分查找的基础上多加一些判断逻辑就可以解决了的啊!
现在我参考了别人的博客,已经写出了解法实现,不知道我的解法是不是最正规的,不过基本测试是通过了:

/**
 * Created by clearbug on 2018/2/26.
 */
public class Solution {

    public static void main(String[] args) {
        Solution s = new Solution();
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 5));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 4));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 3));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 2));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 1));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 15));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 10));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 8));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 6));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 16));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 7));
        System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 9));
    }

    public int search(int[] arr, int target) {
        return searchHelper(arr, 0, arr.length - 1, target);
    }

    private int searchHelper(int[] arr, int start, int end, int target) {
        if (start > end) {
            return -1;
        }

        int middle = (start + end) / 2;
        if (arr[middle] == target) {
            return middle;
        }

        if (arr[middle] < arr[middle - 1] && arr[middle] < arr[middle + 1]) { // middle 即是分割点
            if (target <= arr[end]) {
                start = middle + 1;
            } else {
                end = middle - 1;
            }
            while (start <= end) {
                middle = (start + end) / 2;
                if (arr[middle] == target) {
                    return middle;
                } else if (arr[middle] > target) {
                    end = middle - 1;
                } else {
                    start = middle + 1;
                }
            }
        } else if (arr[middle] > arr[end]) { // middle 在分割点左侧
            if (target > arr[middle]) {
                start = middle + 1;
                return searchHelper(arr, start, end, target);
            } else {
                int leftRes = searchHelper(arr, start, middle - 1, target);
                if (leftRes > -1) {
                    return leftRes;
                }
                int rightRes = searchHelper(arr, middle + 1, start, target);
                if (rightRes > -1) {
                    return rightRes;
                }
            }
        } else { // arr[middle] < arr[end], middle 在分割点右侧
            if (target > arr[middle]) {
                int leftRes = searchHelper(arr, start, middle - 1, target);
                if (leftRes > -1) {
                    return leftRes;
                }
                int rightRes = searchHelper(arr, middle + 1, start, target);
                if (rightRes > -1) {
                    return rightRes;
                }
            } else {
                end = middle - 1;
                return searchHelper(arr, start, end, target);
            }
        }
        return -1;
    }

}

参考

http://www.gocalf.com/blog/circularly-ordinal-array.html

posted @ 2018-03-16 10:28  optor  阅读(974)  评论(2编辑  收藏  举报