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

本文介绍了一种在旋转有序数组中查找特定元素的算法实现。该算法基于二分查找,并增加了一些额外的判断逻辑来处理数组旋转的情况。文章通过具体实例展示了算法的正确性和有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题目是我在快看漫画面试时的一道算法题: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

转载于:https://www.cnblogs.com/optor/p/8579174.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值