• LeetCode--搜索旋转排序数组


    LeetCode链接: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)级别;

      我的想法是:先找到旋转点,再找目标值target在数组中的索引。这两个查找过程均使用二分查找,时间复杂度为O(log n);

        如果一个有序数组发生了旋转,整体上将不再有序,但是会得到两个部分有序的子数组,如上例中的[4, 5, 6, 7]和[0, 1, 2]这两个部分仍是有序的,所以可以使用二分查找,找到旋转点,旋转点也就是两个有序子数组的分界点;

        找到旋转点后再将target的值与nums[旋转点]的值进行比较,选择在哪个有序子数组里使用二分查找寻找target所对应的索引值

     1 public class Solution {
     2     public int search(int[] nums, int target) {
     3         if(nums == null || nums.length == 0) return -1;
     4         if(nums.length == 1) return nums[0] == target ? 0 : -1;
     5         int left = 0, right = nums.length - 1, mid = 0;
     6         // 先找到旋转点,旋转点也就是两个有序子数组的分界点
     7         int rotateIndex = findRotateIndex(nums);
     8         if(nums[left] > nums[right]) {  // 判断nums是否发生了旋转,如果发生了,那么判断应该在哪个有序子数组里查找
     9             if(target >= nums[left]) {
    10                 right = rotateIndex;
    11             }else {
    12                 left = rotateIndex + 1;
    13             }
    14         }
    15         while(left <= right) {       // 在有序子数组中查找目标值的索引
    16             mid = (left + right) / 2;
    17             if (target > nums[mid]) {
    18                 left = mid + 1;
    19             }
    20             else if(target < nums[mid]){
    21                 right = mid - 1;
    22             }
    23             else {
    24                 return mid;
    25             }
    26         }
    27         return -1;
    28     }
    29     
    30     public int findRotateIndex(int[] nums) {       // 查找旋转点的下标
    31         int left = 0, right = nums.length - 1, mid = 0;
    32         if(nums[left] <= nums[right]) return right;
    33         int rotateIndex = right;   // 记录旋转点,它始终指向的是数组元素的最大值
    34         while(left <= right) {
    35             if(nums[left] <= nums[right]) {          // 当条件成立时,说明该子数组是有序子数组,即找到了两个有序子数组的分界点
    36                 rotateIndex = right < mid ? right : left - 1;
    37                 return rotateIndex;
    38             }
    39             else {
    40                 mid = (left + right) / 2;
    41                 if(nums[left] <= nums[mid]) {
    42                     left = mid + 1;        // 说明旋转点在mid的右边
    43                 }
    44                 else {
    45                     right = mid - 1;       // 说明旋转点在mid的左边
    46                 }
    47             }
    48         }
    49         return rotateIndex;
    50     }
    51 }
  • 相关阅读:
    利用jquery进行ajax提交表单和附带的数据
    jquery插件-validate
    function [eigf,eigv,dof]=laplaceeig(node,elem,problem)
    [A,D]=solverAdini(node,elem,bdEdge,h1,h2)
    Example11(June 9,2015)
    加州旅馆
    jpg/png格式图片转eps格式的方法--latex自带命令bmeps
    accumarray
    HDU 1423 最长公共字串+上升子序列
    HDU 1503 带回朔路径的最长公共子串
  • 原文地址:https://www.cnblogs.com/OoycyoO/p/11756926.html
Copyright © 2020-2023  润新知