Leetcode 33 搜索旋转排序数组

33. 搜索旋转排序数组

题意:整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,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] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

解题思路

解法1:
1.贪心算法,遍历数组,找到目标值,则返回出现位置,否则返回-1

解法2:
1.分析题意,实际上原数组是有序序列,针对于有序列表,我们还是想用二分查找,这样时间复杂度可以为O(log n),可是题目的难处在于,输入为翻转k次后的数组,而我们不知道翻转了多少次,无法还原数组
2.先根据 nums[mid] 与 nums[left] 的关系判断 mid 是在左段还是右段,接下来再判断 target 是在 mid 的左边还是右边,从而来调整左右边界 left 和 right
如果mid大于左端值,说明左端是有序数组,然后在有序数组中找寻target,target与mid,从而判断target是出现在[left,mid]的左端还是右端

解题遇到的问题

后续需要总结学习的知识点

##解法1
class Solution {
    public int search(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == target) {
                return i;
            }
        }
        return -1;
    }
}

##j解法2
class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            }

            // 如果mid大于左端值,说明左端是有序数组
            if (nums[left] <= nums[mid]) {
                // target与mid,从而判断target是出现在[left,mid]的左端还是右端
                if (nums[left] <= target && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            } else {
                if (nums[mid] < target && target <= nums[right]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
        }
        return -1;
    }
}

你可能感兴趣的:(Leetcode 33 搜索旋转排序数组)