LeetCode搜索旋转排序数组

本文涉及 4 道「搜索旋转排序数组」题:

  • LeetCode 33 题:搜索旋转排序数组
  • LeetCode 81 题:搜索旋转排序数组-ii
  • LeetCode 153 题:寻找旋转排序数组中的最小值
  • LeetCode 154 题:寻找旋转排序数组中的最小值-ii

可以分为 3 类:

  • 33、81 题:搜索特定值
  • 153、154 题:搜索最小值
  • 81、154 题:包含重复元素
  • LeetCode 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 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • class Solution {
        public int search(int[] nums, int target) {
            int low = 0;
            int high = nums.length - 1;
            while (low <= high) {
                int mid = low + (high - low) / 2;
                if (nums[mid]==target)
                    return mid;
                else if (nums[low]<=nums[mid]){
                    if (nums[low] <= target && target <=nums[mid])
                        high = mid-1;
                    else
                        low = mid+1;
                }else{
                    if (nums[mid] <= target && target <=nums[high])
                        low = mid+1;
                    else
                        high = mid -1;
    
                }
            }
            return -1;
        }
    }

  • LeetCode 81 题:搜索旋转排序数组-ii (会有重复数)
  • 对于数组中有重复元素的情况,二分查找时可能会有 a[l]=a[mid]=a[r]。

    例如 \nums=[3,1,2,3,3,3,3],target=2,首次二分时无法判断区间 [0,3] 和区间 [4,6] 哪个是有序的。

    对于这种情况,我们只能将当前二分区间的左边界加一,右边界减一,然后在新区间上继续二分查找。
    链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/solution/sou-suo-xuan-zhuan-pai-xu-shu-zu-ii-by-l-0nmp/
     

  • class Solution {
        public boolean search(int[] nums, int target) {
            int n = nums.length;
            if (n == 0) {
                return false;
            }
            int l = 0, r = n - 1;
            while (l <= r) {
                int mid = (l + r) / 2;
                if (nums[mid] == target) {
                    return true;
                }
                if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
                    ++l;
                    --r;
                } else if (nums[l] <= nums[mid]) {
                    if (nums[l] <= target && target < nums[mid]) {
                        r = mid - 1;
                    } else {
                        l = mid + 1;
                    }
                } else {
                    if (nums[mid] < target && target <= nums[n - 1]) {
                        l = mid + 1;
                    } else {
                        r = mid - 1;
                    }
                }
            }
            return false;
        }
    }
    
    

  • LeetCode 153 题:寻找旋转排序数组中的最小值
  • 如果中值比右边的值还大,有旋转在右边,left=mid+1;
  • 否则 慢慢缩小右边界
class Solution {
    public int findMin(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] > nums[right]) {          
                left = mid + 1;
            } else {                                
                right = mid;
            }
        }
        return nums[left];
    }
};

  • LeetCode 154 题:寻找旋转排序数组中的最小值-ii
  • 与上一题类似 可能有重复数组 当数值重复的时候 右边界--,去掉重复
class Solution {
    public int findMin(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] > nums[right]) {          
                left = mid + 1;
            } else if(nums[mid] < nums[right]){                                
                right = mid;
            }else{
                right --;
            }
        }
        return nums[left];
    }
};

你可能感兴趣的:(leetcode)