LeetCode33. 搜索旋转排序数组

LeetCode33. 搜索旋转排序数组

题目描述

/**
     * 
     * 整数数组 nums 按升序排列,数组中的值 互不相同 。
     * <p>
     * 在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,
     * 使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]
     * (下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
     * <p>
     * 给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,
     * 则返回它的下标,否则返回 -1 。
     * 
     */

思路分析

  1. 此题目中原数组是顺序排列的,但是经旋转后数组不绝对顺序排列
  2. 由题目可知,将此旋转后的数组从中间分开后,总能保证有一半是顺序的,而另一半则是没有排序的
  3. 因此顺序的一半可以使用二分查找,不过要先判断target是否在这个顺序的一半数组中
  4. 如果在顺序的数组中,则直接二分查找,否则重新将另一半没有排序的数组从中间分开,仍然能保证一半是顺序的,一般是没有顺序的,依次上述方法即可
  5. 实现如下

源码及分析

//思路分析:局部二分查找
    /**
     *
     * @param nums    要查找的旋转数组
     * @param target  目标值
     * @return        返回的元素位置,索引
     */
    public int search(int[] nums, int target) {
        //定义变量保存数组长度
        int len = nums.length;
        //数据校验
        if (nums == null || len == 0) {
            return -1;
        }
        //目标值所在的索引
        int index = -1;
        //数组左右边界下标
        int left = 0, right = len - 1;
        while (left <= right) {
            //数组中间元素的大小
            int mid = (left + right) / 2;
            //判断数组前半部分有序还是后半部分有序,如果前半部分有序
            if (nums[mid] >= nums[left]) {
                //判断target是否在此区间
                if (target >= nums[left] && target <= nums[mid]) {
                    //如果在此区间,查找target值
                    if (nums[mid] == target) {
                        index = mid;
                        left = mid + 1;
                    } else if (nums[mid] > target) {
                        right = mid - 1;
                    } else {
                        left = mid + 1;
                    }
                    //如果不在此区间,缩小查找范围
                } else {
                    left = mid + 1;
                }
            } else {
                //如果后半部分有序
                //判断target是否在此区间
                if (target >= nums[mid] && target <= nums[right]) {
                    if (nums[mid] == target) {
                        index = mid;
                        left = mid + 1;
                    } else if (nums[mid] > target) {
                        right = mid - 1;
                    } else {
                        left = mid + 1;
                    }
                } else {
                    right = mid - 1;
                }
            }
        }
        return index;
    }

posted @ 2021-05-24 10:14  mx_info  阅读(50)  评论(0)    收藏  举报