LeetCode33—搜索旋转排序数组
方法一:先找到旋转点,然后根据目标值重新确定二分查找区域。
时间复杂度:用到两次二分查找,每次二分查找粗略的认为是O(logn),那么时间复杂度为2 * O(logn);
空间复杂度:O(1)。
1 int search(vector<int>& nums, int target) { 2 if (!nums.size()) return -1; 3 4 int low = 0, high = nums.size() - 1, mid; 5 int rotate = 0; //旋转点 6 //第一步先找到旋转点 7 if (nums[low] <= nums[high]) rotate = 0; //无旋转 8 else 9 { 10 while (low < high) 11 { 12 mid = low + ((high - low) >> 1); 13 if (nums[mid] > nums[mid + 1]) break; 14 15 if (nums[mid] >= nums[low]) low = mid; 16 else high = mid; 17 } 18 rotate = mid + 1; 19 } 20 //重新规划二分查找区域 21 if (!rotate) 22 { 23 low = 0; 24 high = nums.size() - 1; 25 } 26 else 27 { 28 if (nums[0] == target) return 0; 29 else if (nums[0] > target) 30 { 31 low = rotate; 32 high = nums.size() - 1; 33 } 34 else 35 { 36 low = 0; 37 high = rotate - 1; 38 } 39 } 40 //二分查找 41 while (low <= high) 42 { 43 mid = low + ((high - low) >> 2); 44 if (nums[mid] == target) return mid; 45 else if (nums[mid] > target) high = mid - 1; 46 else low = mid + 1; 47 } 48 49 return -1; 50 }
方法二:根据中间点和其他条件来调整上下边界。其实一开始就想的这个办法,但是写的过程中发现很混乱,所以就写了上一种比较清晰的方法。这个方法的关键是确定哪半边是有序的,在这个前提下分情况讨论会很清晰。
时间复杂度:O(logn),空间复杂度:O(1)。
1 int search(vector<int>& nums, int target) { 2 if (!nums.size()) return -1; //数组为空 3 4 int low = 0, high = nums.size() - 1, mid; 5 if (nums[low] <= nums[high]) //数组无旋转点,即升序排列 6 { 7 while (low <= high) 8 { 9 mid = low + ((high - low) >> 1); 10 if (nums[mid] == target) return mid; 11 else if (nums[mid] > target) high = mid - 1; 12 else low = mid + 1; 13 } 14 return -1; 15 } 16 else //数组有旋转点 17 { 18 while (low <= high) 19 { 20 mid = low + ((high - low) >> 1); 21 if (nums[mid] == target) return mid; 22 23 if (nums[mid] > nums[low]) //左半边有序 24 { 25 if (nums[low] < target && nums[mid] > target) high = mid - 1; 26 else if (nums[low] == target) return low; 27 else low = mid + 1; 28 } 29 else //右半边有序 30 { 31 if (nums[high] > target && nums[mid] < target) low = mid + 1; 32 else if (nums[high] == target) return high; 33 else high = mid - 1; 34 } 35 } 36 return -1; 37 } 38 }
总结:1)分析时把握问题的特征,不要没有头绪的想,不然就是猜了;
2)O(logn)复杂度是非常优秀的时间复杂度。