二分查找

35. Search Insert Position

题目链接:https://leetcode.com/problems/search-insert-position/?tab=Description

题目大意:给定一个有序数组和一个目标值,如果目标值在数组中,则返回其所在的位置,如果不存在,则返回目标值的插入位置,该位置使得目标值插入后,数组仍旧保持有序

思路:二分查找,每次比较数组中间值和目标值的大小,如果目标值比中间值大,压缩数组的左半部分,如果目标值比中间值小,则压缩数组的右半部分。

算法步骤:(1)初始化low=0,high=nums.size()-1;(2)比较当前数组(由low和high表示数组范围)中间值和target的大小,如果target大,则令low=mid+1,若target小,则high=mid-1,否则直接返回index;(3)如果low<=high,重复步骤(2),否则返回low。(如果最后一次比较target值比中间值(即low位置的值)大,low所在位置为刚好大于target值得位置,如果target值比中间值(即high位置的值)小,更新low=mid+1,如果mid+1有值,则根据high的上一轮更新知道mid+1所在位置一定大于target,如果mid+1等于数组长度,则target插入此处,数组也是有序的)

算法复杂度:时间复杂度O(nlog(n)),空间复杂度O(1)

代码:

 1 class Solution {
 2 public:
 3     int searchInsert(vector<int>& nums, int target) {
 4         int low = 0, high = nums.size() - 1;
 5         while (low <= high) {
 6             int mid = (high - low) / 2 + low;
 7             if (target < nums[mid])
 8                 high = mid - 1;
 9             else if (target > nums[mid])
10                 low = mid + 1;
11             else
12                 return mid;
13         }
14         return low;
15     }
16 };

评测系统上运行结果:

 153. Find Minimum in Rotated Sorted Array

题目链接:https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/?tab=Description

题目大意:给定一个按升序排好序的数组,数组在某处执行了一次旋转,请找出数组的最小元素,数组不存在重复值

思路:二分查找的变体,重要的是找到转折点发生的位置,转折点位置的值就是最小值

算法步骤:(1)初始化left=0,right=nums.size()-1;(2)比较当前数组(由left和right表示数组范围)中间值和nums[right]的大小,如果nums[right]大,说明转折点不在右侧,更新right=mid,若nums[right]小,说明转折点在右侧,更新left=mid+1;(3)如果left<right,重复步骤(2),若left==right,说明转折点已经找到,返回nums[left]。

算法复杂度:时间复杂度O(nlog(n)),空间复杂度O(1)

代码:

 1 class Solution {
 2 public:
 3     int findMin(vector<int>& nums) {
 4         int left = 0, right = nums.size() - 1;
 5         while (left < right) {
 6             int mid = left + (right - left) / 2;
 7             if (nums[mid] < nums[right])
 8                 right = mid;
 9             else
10                 left = mid + 1;
11         }
12         return nums[left];
13     }
14 };

154. Find Minimum in Rotated Sorted Array II

链接:https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/?tab=Description

题目大意:给定一个按升序排好序的数组,数组在某处执行了一次旋转,请找出数组的最小元素,数组存在重复值

思路:二分查找的变体,重要的是找到转折点发生的位置,转折点位置的值就是最小值

算法步骤:(1)初始化left=0,right=nums.size()-1;(2)比较当前数组(由left和right表示数组范围)中间值和nums[right]的大小,如果nums[right]大,说明转折点不在右侧,更新right=mid,若nums[right]小,说明转折点在右侧,更新left=mid+1,若nums[right]==nums[mid],则最小值可能在左侧,也可能在右侧,但不论在哪侧,都可以通过--right,将数组范围缩小一点;(3)如果left<right,重复步骤(2),若left==right,说明转折点已经找到,返回nums[left]。

算法复杂度:时间复杂度O(nlog(n)),空间复杂度O(1)

代码:

 1 class Solution {
 2 public:
 3     int findMin(vector<int>& nums) {
 4         int left = 0, right = nums.size() - 1;
 5         while (left < right) {
 6             int mid = left + (right - left) / 2;
 7             if (nums[mid] < nums[right])
 8                 right = mid;
 9             else if(nums[mid] > nums[right])
10                 left = mid + 1;
11             else
12                 --right;
13         }
14         return nums[left];
15     }
16 };

原文地址:https://www.cnblogs.com/gxhblog/p/6506643.html