zoukankan      html  css  js  c++  java
  • 0033. Search in Rotated Sorted Array (M)

    Search in Rotated Sorted Array (M)

    题目

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

    (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).

    You are given a target value to search. If found in the array return its index, otherwise return -1.

    You may assume no duplicate exists in the array.

    Your algorithm's runtime complexity must be in the order of O(log n).

    Example 1:

    Input: nums = [4,5,6,7,0,1,2], target = 0
    Output: 4
    

    Example 2:

    Input: nums = [4,5,6,7,0,1,2], target = 0
    Output: 4
    

    题意

    将一递增数列的随机后半部分与前半部分换位,得到新数组,在新数组中查找目标值。

    思路

    比较简单的做法是先用一个二分找到两个递增序列的边界,再用一个二分在对应的递增序列里查找目标值。

    也可以只用一个二分完成操作:求出mid,先考虑mid落在右递增区间的情况,如果target也落在右递增区间且比nums[mid]大,说明只需要继续向右查找,令 left = mid + 1 即可,不然只要向左查找,令 right = mid - 1;同理,对于mid落在左递增区间的情况进行处理。


    代码实现

    Java

    不求边界

    class Solution {
        public int search(int[] nums, int target) {
            int left = 0;
            int right = nums.length - 1;
            
            while (left <= right) {
                int mid = (left + right) / 2;
                if (nums[mid] == target) {
                    return mid;
                }
                // 通过与第一个值相比较来判断mid落在左区间还是右区间
                if (nums[mid] < nums[left]) {
                    if (target <= nums[right] && target > nums[mid]) {
                        left = mid + 1;
                    } else {
                        right = mid - 1;
                    }
                } else {
                    if (target >= nums[left] && target < nums[mid]) {
                        right = mid - 1;
                    } else {
                        left = mid + 1;
                    }
                }
            }
            
            return -1;
        }
    }
    

    先求边界

    class Solution {
        public int search(int[] nums, int target) {
            if (nums.length == 0) {
                return -1;
            }
            
            int left = 0;
            int right = nums.length - 1;
            int split = nums.length - 1;		// 默认不存在边界
            
            while (left <= right) {
                int mid = (left + right) / 2;
                if (nums[mid] == target) {
                    return mid;
                }
                if (nums[mid] >= nums[left]) {
                    if (mid + 1 < nums.length && nums[mid + 1] < nums[mid]) {
                        split = mid;
                        break;
                    } else {
                        left = mid + 1;
                    }
                } else {
                    if (mid - 1 >= 0 && nums[mid - 1] > nums[mid]) {
                        split = mid - 1;
                        break;
                    } else {
                        right = mid - 1;
                    }
                }
            }
    		
            // 选择一个递增区间进行二分查找
            if (target >= nums[0]) {
                return binarySearch(nums, 0, split, target);
            } else {
                return binarySearch(nums, split + 1, nums.length - 1, target);
            }
        }
    
        private int binarySearch(int[] nums, int left, int right, int target) {
            while (left <= right) {
                int mid = (left + right) / 2;
                if (target > nums[mid]) {
                    left = mid + 1;
                } else if (target < nums[mid]) {
                    right = mid - 1;
                } else {
                    return mid;
                }
            }
            return -1;
        }
    }
    

    JavaScript

    /**
     * @param {number[]} nums
     * @param {number} target
     * @return {number}
     */
    var search = function (nums, target) {
      let left = 0, right = nums.length - 1
      while (left <= right) {
        let mid = Math.trunc((right - left) / 2) + left
    
        if (nums[mid] === target) {
          return mid
        }
    
        if (target < nums[0] && nums[mid] >= nums[0]) {
          left = mid + 1
        } else if (target >= nums[0] && nums[mid] < nums[0]) {
          right = mid - 1
        } else if (nums[mid] < target) {
          left = mid + 1
        } else {
          right = mid - 1
        }
      }
      
      return -1
    }
    
  • 相关阅读:
    quartz 中JobExecutionContext的使用
    Memcached 集群架构方面的问题
    Spring+Quartz 集群
    Spring Quartz 持久化解决方案
    不同版本(2.3,2.4,2.5) web.xml 的web-app头信息
    Spring Framework 4.0.0发布,首次支持Java 8
    Serializable java序列化
    Quartz 有状态的JobDataMap
    JobDataMap 不能被序列化如何解决研究中
    Spring-3.2.5 + Quartz-2.2.1 集群实例(Tomcat+Memcached+Quartz集群session共享)
  • 原文地址:https://www.cnblogs.com/mapoos/p/13190987.html
Copyright © 2011-2022 走看看