zoukankan      html  css  js  c++  java
  • leetcode刷题笔记三十三 搜索旋转排序数组

    leetcode刷题笔记三十三 搜索旋转排序数组

    源地址:33. 搜索旋转排序数组

    问题描述:

    假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [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(logn),对于本题的第一想法就是使用二分法进行查找。
    //由于可能存在旋转点,整个有序数组可被分割为一个有序数组或者两个有序数组
    //简单的思路是通过对一个或两个有序数组,确认最小值点,即旋转点
    //对旋转点两侧进行二分查找
    //进一步方法是通过对nums(0)、nums(mid)和target比较
    //具体可分为7种情况
    //1. target == nums(mid) 这种情况下 return mid
    //
    //2. tPoint < target && target < nums(mid)
    // (tPoint target nums(mid) max)(min .. size-1)
    // right = mid -1
    //
    //3. tPoint <= nums(mid) && nums(mid) <= target
    // (tPoint nums(mid) target max)(min .. size-1)
    // left = mid + 1
    //
    //4. nums(mid) < tPoint && target < nums(mid)
    //(tPoint .. max)(min target nums(mid) size-1)
    // right = mid -1
    //
    //5. target <= tPoint && nums(mid) <= target
    //(tPoint .. max)(min nums(mid) target size-1)
    // left = mid + 1
    //
    //6. target <= tPoint && tPoint <= nums(mid)
    //(tPoint nums(id) max)(min target size-1)
    //left = mid + 1
    //
    //7. nums(mid) < tPoint && tPoint < target
    //(tPoint target max)(min nums(id) size-1)
    //right = mid -1
    object Solution {
        def search(nums: Array[Int], target: Int): Int = {
            if (nums.length == 0) return -1
            if (nums.length == 1 && nums(0) != target) return -1
            var left = 0
            var right = nums.length - 1
            val tPoint = nums(0)
            var ans = 0
            if (nums(left) == target) return left
            if (nums(right) == target)  return right
            while(left <= right){
                var mid = (left + right)/2
                (tPoint, target, nums(mid)) match {
                    case s0 if target == nums(mid) => {ans = mid;  return ans} 
                    case s1 if (tPoint < target && target < nums(mid)) => {right = mid -1}
                    case s2 if (tPoint <= nums(mid) && nums(mid) <= target) => {left = mid + 1}
                    case s3 if (nums(mid) < tPoint && target < nums(mid)) => {right = mid -1}
                    case s4 if (target <= tPoint && nums(mid) <= target) => {left = mid + 1}
                    case s5 if (target <= tPoint && tPoint <= nums(mid)) => {left = mid + 1}
                    case s6 if (nums(mid) < tPoint && tPoint < target) => {right = mid -1}
                    case _ => return -1
                }
            }
            return -1
        }
    }
    
    //简化的方法  通过上述方法可以得知我们只需要(nums[0] <= target), (target <= nums[i]) ,(nums[i] < nums[0])
    //进行判断
    //显然,这三者不可能均不成立或均成立
    //所以我们只需要通过异或的方法判断是一个成立,还是二个成立
    //两项为真时,向前规约
    //一项为真时,向后规约
    object Solution {
        def search(nums: Array[Int], target: Int): Int = {
            var left = 0
            var right = nums.length - 1
            while(left < right){
                var mid = (left + right)/2
                if((nums(0) > target) ^ (nums(0) > nums(mid)) ^ (target > nums(mid))) left = mid + 1
                else right = mid
            }
            if (left == right && nums(left) == target) return left
            else return -1
        }
    }
    
  • 相关阅读:
    zookeeper基础笔记
    基于spring@aspect注解的aop实现
    Struts2中的开启AsyncContext的方法
    在执行gem install redis时 : ERROR: Error installing redis: redis requires Ruby version >= 2.2.2
    ConcurrentHashMap原理笔记
    Java并发Condition原理分析
    CountDownLatch实现原理
    ThreadPoolExecutor 线程池原理分析
    HashMap原理
    线程池的用法
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/12846853.html
Copyright © 2011-2022 走看看