zoukankan      html  css  js  c++  java
  • [LeetCode] 33. 搜索旋转排序数组

    题目链接: https://leetcode-cn.com/problems/search-in-rotated-sorted-array/

    题目描述:

    假设按照升序排序的数组在预先未知的某个点上进行了旋转。

    ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

    搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1

    你可以假设数组中不存在重复的元素。

    你的算法时间复杂度必须是 O(log n) 级别。

    示例:

    示例 1:

    输入: nums = [4,5,6,7,0,1,2], target = 0
    输出: 4
    

    示例 2:

    输入: nums = [4,5,6,7,0,1,2], target = 3
    输出: -1
    

    思路:

    题目中说明要用O(log n)能想到就是二分法!

    思路一:

    整体思路:先用二分法找出最小值,也是那个分割点,例如[4,5,6,7,0,1,2],我们找出数字0;

    接下来判断target是在分割点的左边还是右边;

    最后再使用一次二分法找出target的位置. 所以时间复杂度为:(O(logn))

    只有一个难点,那就是如何通过二分法找出那个分割点呢?

    就是和它的右端点比较判断,直接看代码吧!

    思路二:

    直接使用二分法,

    判断那个二分点,有几种可能性

    1. 直接等于target

    2. 在左半边的递增区域

      a. targetleftmid 之间

      b.不在之间

    3. 在右半边的递增区域

      a. targetmidright 之间

      b. 不在之间

    思路三:

    参考链接1

    参考链接2

    还是很容易理解的!


    关注我的知乎专栏,了解更多解题技巧,大家共同进步!

    代码:

    方法一:

    python

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            if not nums:return -1
            n = len(nums)
            left = 0
            right = len(nums) - 1
            while left < right:
                mid = left + (right - left) //2
                if nums[mid] > nums[right]:
                    left = mid + 1
                else:
                    right = mid
            t = left
            left = 0
            right = len(nums) - 1
            while left <= right:
                mid = (left + right) //2
                realmid = (mid + t) % n
                if nums[realmid] == target:
                    return realmid
                elif nums[realmid] > target:
                    right = mid - 1
                else:
                    left = mid + 1
            return -1
    

    java

    class Solution {
        public int search(int[] nums, int target) {
            if (nums == null || nums.length == 0) return -1;
            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;
            }
            //System.out.println(left);
            int split_t = left;
            left = 0;
            right = nums.length - 1;
            if (nums[split_t] <= target && target <= nums[right]) left = split_t;
            else right = split_t;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] == target) return mid;
                else if (nums[mid] > target) right = mid - 1;
                else left = mid + 1;
            }
            return -1;
            
        }
    }
    

    方法二

    python

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            n = len(nums)
            if n == 0:
                return -1
            left = 0
            right = n - 1
            while left < right:
                mid = left + (right - left) // 2
                if nums[mid] == target:
                    return mid
                elif nums[left] <= nums[mid]:
                    if nums[left] <= target < nums[mid]:
                        right = mid - 1
                    else:
                        left = mid + 1
                else:
                    if nums[mid] < target <= nums[right]:
                        left = mid + 1
                    else:
                        right = mid - 1
            #print(left,right)
            return left if nums[left] == target else -1
    

    java

    class Solution {
        public int search(int[] nums, int target) {
            if (nums == null || nums.length == 0) return -1;
            int n = nums.length;
            int left = 0;
            int right = n - 1;
            while (left < right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] == target) return mid;
                else if (nums[left] <= nums[mid]) {
                    if (nums[left] <= target && target < nums[mid]) right = mid - 1;
                    else left = mid + 1;
    
                } else if (nums[mid] < nums[right]) {
                    if (nums[mid] < target && target <= nums[right]) left = mid + 1;
                    else right = mid - 1;
                } 
            }
            return nums[left] == target ? left : -1;
            
        }
    }
    

    思路三:

    python

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            n = len(nums)
            if n == 0:
                return -1
            left = 0
            right = n 
            while left < right:
                mid = left + (right - left) // 2
                # if (target < nums[0] and nums[mid] < nums[0]) or 
                # (target > nums[0] and nums[mid] > nums[0])
                if (nums[mid] < nums[0]) == (target < nums[0]):
                    num = nums[mid]
                else:
                    if target < nums[0]:
                        num = float("-inf")
                    else:
                        num = float("inf")
                if num < target:
                    left = mid + 1
                elif num > target:
                    right = mid
                else:
                    return mid
            return -1
    

    java

    class Solution {
        public int search(int[] nums, int target) {
            if (nums == null || nums.length == 0) return -1;
            int left = 0;
            int right = nums.length;
            while (left < right) {
                int mid = left + (right - left) / 2;
                long  num = (nums[mid] < nums[0]) == (target < nums[0])
                        ? nums[mid]
                        : target < nums[0] ? Long.MIN_VALUE: Long.MAX_VALUE;
                if (num < target) left = mid + 1;
                else if (num > target) right = mid;
                else return mid;
            }
            return -1;
            
        }
    }
    
  • 相关阅读:
    JS 创建对象的几种方式
    JS跨域笔记
    HTML5随笔
    css3随笔
    CSS3最简洁的轮播图
    canvas createRadialGradient 用法
    git 初级
    Oracle数据库字符集与国家字符集
    连接Oracle 19c出现ORA-28040:没有匹配的验证协议
    Vmware workstation虚拟机导入到esxi虚拟机
  • 原文地址:https://www.cnblogs.com/powercai/p/10826453.html
Copyright © 2011-2022 走看看