leetcode刷题记录——二分查找(入门)
——参考代码随想录和力扣顺序刷题(https://programmercarl.com/)
题目目录
35. 搜索插入位置
69. x 的平方根
441. 排列硬币
744. 寻找比目标字母大的最小字母
278. 第一个错误的版本
852. 山脉数组的峰顶索引
367. 有效的完全平方数
1385. 两个数组间的距离值
167. 两数之和 II - 输入有序数组
74. 搜索二维矩阵
350. 两个数组的交集 II
633. 平方数之和
1855. 下标对中的最大距离
33. 搜索旋转排序数组
153. 寻找旋转排序数组中的最小值
1、二分查找
- 版本一
// 版本一
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
while (left < right) { // 因为left==right的时候,在[left, right)是无效的空间,所以使用 <
int middle = left + ((right - left) >> 1);
if (nums[middle] > target) {
right = middle; // target 在左区间,在[left, middle)中
} else if (nums[middle] < target) {
left = middle + 1; // target 在右区间,在[middle + 1, right)中
} else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
- 版本二(一般用来求数组下标且不想开新变量)
// 版本一
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
if (nums[middle] > target) {
right = middle - 1; // target 在左区间,所以[left, middle - 1]
} else if (nums[middle] < target) {
left = middle + 1; // target 在右区间,所以[middle + 1, right]
} else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
35. 搜索插入位置(简单)
- 体会:找临界;找中间位置的第一个比什么什么大的值;找第一个突变的值
69. x 的平方根 (简单)
-
本质:搜索插入位置
-
问题 3:为什么有一些二分查找取 mid 的时候,括号里要加 1?
这是因为 int mid = (left + right) / 2 在区间里有偶数个元素的时候,mid 只能取到位于左边的中间数,要想取到位于右边的中间数,就需要在括号里加 1。
为什么要取右边中间数呢?这是因为在区间里 只有 22 个元素的时候,把 [left…right] 划分成 [left…mid - 1] 和 [mid…right] 这两个区间,int mid = (left + right) / 2 这种取法不能把搜索区间缩小。
理解这件事情最典型的例子是「力扣」第 69 题,详细的分析和调试在 这里。
总之就是为了:避免死循环。
-
思路:
- 如果这个整数的平方 恰好等于输入整数,那么我们就找到了这个整数;
- 如果这个整数的平方 严格大于 输入整数,那么这个整数肯定不是我们要找的那个数;
- 如果这个整数的平方 严格小于 输入整数,那么这个整数 可能 是我们要找的那个数(重点理解这句话)。
作者:liweiwei1419
链接:https://leetcode.cn/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
441. 排列硬币(简单)
-
公式:(1+k)k = 2n
-
本质还是找插入位置(找第一个比2n大的k)相当于返回left - 1(=right)的位置(因为数组索引和值相同,所以位置和值相同)
-
代码:(为什么=要放在 < 这一个条件里面?)
-
解释:因为若k小于2n,则需要在left = middle + 1范围里面找,若k + 1大于2n,则返回的结果是k,因此right没有发生变化,只有left发生变化,所以要放在left(<)条件里面;结束时,left的位置一定是第一个比2n大的k的位置,又因为最后结束一定是right = middle - 1或left = middle + 1 且上一次right = left = middle ,所以right一定等于left - 1;
-
根本原因:加入 = 条件,right就不能改变;
class Solution {
public:
int arrangeCoins(int n) {
int left = 1;
int right = n;
while(left <= right) {
int middle = left + (right - left)/2;
if ((long long) middle * (middle + 1) <= (long long) 2 * n) {
left = middle + 1;
}
else {
right = middle - 1;
}
}
return right;
}
};
744. 寻找比目标字母大的最小字母(简单)
- 本质:搜索插入位置后按照循环队列返回值
278. 第一个错误的版本(简单)
- 本质:搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-insert-position
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
思路:
-
二分搜索(思考为什么找不到则返回left)
-
理解(不考虑nums[0]>target或nums[nums.size()-1]<target):循环结束临界条件为 left == right 退出条件为 left(middle + 1) > right 或者 right(middle - 1) > left
① 当 left(middle + 1) > right时,表示 nums[middle] < target,所以target大于左边的所有数并且大于当前位置的数,当前位置(middle + 1)= left 即插入位置。
② 当 right(middle - 1) > left时,表示nums[middle] > target,所以target小于右边的所有数并且小于当前位置的数,当前位置 left 即为插入位置。
代码:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
int middle;
while (left <= right) {
middle = left + (right - left)/2; //防止溢出
if(nums[middle] < target) {
left = middle + 1;
}
else if (nums[middle] > target) {
right = middle -1;
}
else if (nums[middle] == target) {
return middle;
}
}
return left;
}
};
852. 山脉数组的峰顶索引(中等)
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-perfect-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
- 找到那个arr[i]>arr[i+1]的数,看递增还是递减的趋势
- 注意的点:需要注意数组越界的情况,取值注意从(1~n-1)
代码:
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int left = 1;
int right = arr.size()-1;
while(left < right) {
int middle = left + (right-left)/2;
if (arr[middle] > arr[middle+1]) {
right = middle;
}
else {
left = middle + 1;
}
}
return left;
}
};
367. 有效的完全平方数(简单)
给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
(进阶:不要使用任何内置的库函数,如 sqrt)
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-perfect-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
- 从0~num之间利用二分查找方法进行比较,注意long square = (long)middle * middle;
- 两个int int型变量相乘结果显示溢出,虽然square已经声明为long long,但是int int的结果先放在int变量中,与前面的变量类型无关。
代码:
class Solution {
public:
bool isPerfectSquare(int num) {
int left = 1;
int right = num;
while (left <= right) {
int middle = left + (right - left)/2;
long square = (long)middle * middle;
if (square > num) {
right = middle -1;
}
else if (square < num) {
left = middle + 1;
}
else if (square == num) {
return true;
}
}
return false;
}
};
1385. 两个数组间的距离值(简单)
给你两个整数数组 arr1 arr2 和一个整数 d ,请你返回两个数组之间的[距离值]。
[距离值] 定义为符合此距离要求的元素数目:对于元素 arr1[i] ,不存在任何元素 arr2[j] 满足 |arr1[i]-arr2[j]| <= d 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-the-distance-value-between-two-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
- 利用high和low指针,分别指向符合条件距离的最大值和最小值(绝对值化简);
- 否则利用二分查找进行搜索;
- 理解为:对于arr2的距离范围:[min,max];
- 好处:化简绝对值消除负数正数加减的影响(不用分类讨论);
代码:
class Solution {
public:
int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d) {
sort(arr2.begin(), arr2.end());
int ans = 0;
for (auto num1 : arr1) {
int low = num1 - d;
int high = num1 + d;
if (!binarySearch(arr2, low, high)) {
ans++;
}
}
return ans;
}
bool binarySearch(vector<int>& arr, int low, int high) {
int left = 0;
int right = arr.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] >= low && arr[mid] <= high) {
return true;
}
else if (arr[mid] < low) {
left = mid + 1;
}
else if (arr[mid] > high) {
right = mid - 1;
}
}
return false;
}
};
167. 两数之和 II - 输入有序数组(中等)
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
思路1:
- 固定一个数,从这个数右边找target - numbers[i],二分查找;
代码:
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
for(int i=0;i<numbers.size();i++){
int left = i+1;
int right = numbers.size()-1;
int temp = target - numbers[i];
while(left <= right) {
int middle = left + (right - left)/2;
if(temp == numbers[middle]) {
return {i+1,middle+1};
}
else if(temp > numbers[middle]) {
left = middle + 1;
}
else {
right = middle - 1;
}
}
}
return {-1,-1};
}
};
思路2:
- 双指针,low(指向最低位),high(指向最高位);有点像快排;
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int low = 0;
int high = numbers.size() - 1;
while(low < high) {
int sum = numbers[low] + numbers[high];
if(sum < target) low++;
else if (sum > target) high--;
else return {low+1,high+1};
}
return {-1,-1};
}
};
74. 搜索二维矩阵(中等)
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-a-2d-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
思路1:
- 从第一行开始递归,用二分查找来找到需要找的值
代码:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int i=0;
while(i<matrix.size()) {
int left = 0;
int right = matrix[i].size() - 1;
while(left<=right) {
int middle = left + (right - left)/2;
if(matrix[i][middle] == target) return true;
else if (matrix[i][middle] > target) {
right = middle - 1;
}
else {
left = middle + 1;
}
}
i+=1;
}
return false;
}
};
思路2:
- 将整个矩阵看成一个递增的一维数组
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m = matrix.size();
int n = matrix[0].size();
int left = 0;
int right = m*n -1;
while(left<=right) {
int middle = left + (right - left)/2;
if(matrix[middle/n][middle%n] == target) {
return true;
}
else if(matrix[middle/n][middle%n] > target) {
right = middle - 1;
}
else{
left = middle + 1;
}
}
return false;
}
};
350. 两个数组的交集 II(简单)
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
思路1:
- 循环第一个数组,对第二个数组进行二分查找;
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());
vector<int> ans;
int j = 0;
for(int i=0;i<nums1.size();i++) {
int flag = 0;
int left = j;
int right = nums2.size()-1;
int middle;
while(left<=right) {
middle = left + (right - left)/2;
if (nums1[i] == nums2[middle]) {
flag = 1;
j = middle + 1;
right = middle - 1;
}
else if (nums1[i] > nums2[middle]) {
left = middle + 1;
}
else {
right = middle - 1;
}
}
if(flag) {
ans.push_back(nums2[left]);
}
}
return ans;
}
};
思路2:
- 排序 + 双指针
- 初始时,两个指针分别指向两个数组的头部。每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位,如果两个数字相等,将该数字添加到答案,并将两个指针都右移一位。当至少有一个指针超出数组范围时,遍历结束。
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());
int left = 0;
int right = 0;
vector<int> ans;
while(left < nums1.size() && right < nums2.size()) {
if(nums1[left] == nums2[right]) {
ans.push_back(nums2[right]);
left++;
right++;
}
else if(nums1[left] > nums2[right]) {
right++;
}
else left++;
}
return ans;
}
};
复杂度分析
- 时间复杂度:O(mlogm+nlogn),其中 mm 和 nn 分别是两个数组的长度。对两个数组进行排序的时间复杂度是 O(mlogm+nlogn),遍历两个数组的时间复杂度是 O(m+n),因此总时间复杂度是 O(mlogm+nlogn)。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/intersection-of-two-arrays-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
633. 平方数之和(中等)
给定一个非负整数 c
,你要判断是否存在两个整数 a
和 b
,使得 a2 + b2 = c
。
示例 1:
输入:c = 5
输出:true
解释:1 * 1 + 2 * 2 = 5
示例 2:
输入:c = 3
输出:false
思路1:
- 先固定一个数,再用二分找第二个数(超时)
思路2:
- 双指针
- 如下图所示:low = 0 , high = sqrt© 用low²和high²来进行比较
- 如果
low² + high² < c
=》low++
- 如果
low² + high² > c
=》high--
- 解释:对角线相当于
low² + high²
的值,low++
相当于让格子向下移动,覆盖整一行,high--
相当于格子左移动,在这一行上进行移动,而整个表格从上到下从左到右都是递增的,因此可以找到目标c;
- 解释:对角线相当于
作者:ggt55ng6
链接:https://leetcode.cn/problems/sum-of-square-numbers/solution/shuang-zhi-zhen-de-ben-zhi-er-wei-ju-zhe-ebn3/
代码:
class Solution {
public:
bool judgeSquareSum(int c) {
int low = 0;
int high = sqrt(c);
while(low<=high) {
long long sum = (long long) low*low + (long long) high*high;
if(sum == c) return true;
else if(sum > c) high--;
else if(sum < c) low++;
}
return false;
}
};
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sum-of-square-numbers/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处
1855. 下标对中的最大距离(中等)
给你两个 非递增 的整数数组 nums1 和 nums2 ,数组下标均 从 0 开始 计数。下标对 (i, j) 中 0 <= i < nums1.length 且 0 <= j < nums2.length 。如果该下标对同时满足 i <= j 且 nums1[i] <= nums2[j] ,则称之为 有效 下标对,该下标对的 距离 为 j - i 。返回所有 有效 下标对 (i, j) 中的 最大距离 。如果不存在有效下标对,返回 0 。一个数组 arr ,如果每个 1 <= i < arr.length 均有 arr[i-1] >= arr[i] 成立,那么该数组是一个 非递增 数组。
示例 1:
输入:nums1 = [55,30,5,4,2], nums2 = [100,20,10,10,5]
输出:2
解释:有效下标对是 (0,0), (2,2), (2,3), (2,4), (3,3), (3,4) 和 (4,4) 。
最大距离是 2 ,对应下标对 (2,4) 。
示例 2:
输入:nums1 = [2,2,2], nums2 = [10,10,1]
输出:1
解释:有效下标对是 (0,0), (0,1) 和 (1,1) 。
最大距离是 1 ,对应下标对 (0,1) 。
示例 3:
输入:nums1 = [30,29,19,5], nums2 = [25,25,25,25,25]
输出:2
解释:有效下标对是 (2,2), (2,3), (2,4), (3,3) 和 (3,4) 。
最大距离是 2 ,对应下标对 (2,4) 。
思路1:
- 固定一个数组的值,对第二个数组进行二分查找
class Solution {
public:
int maxDistance(vector<int>& nums1, vector<int>& nums2) {
int maxd = 0;
for(int i=0;i<nums1.size();i++) {
int left = i;
int right = nums2.size()-1;
while(left<=right) {
int middle = left + (right - left)/2;
if(nums2[middle] >= nums1[i]) {
if(middle - i > maxd) maxd = middle - i;
left = middle + 1;
}
else right = middle - 1;
}
}
return maxd;
}
};
思路2:
- 双指针
- 定义p1,p2 如果nums1[p1] > nums2[p2],则没有距离,p1p2都要加1(递减且保证p1<=p2)就不会出现:if(left > right) right = left;(自己的步骤)
- 如果p1 != p2 则一定是p1<p2
class Solution {
public int maxDistance(int[] nums1, int[] nums2) {
int p1 = 0;
int p2 = 0;
int res = 0;
while (p1 < nums1.length && p2 <nums2.length){
if(nums1[p1] > nums2[p2]){ //无效
if(p1 == p2){
p1++;
p2++;
}else p1++;
}else { //有效
res =Math.max(res,p2-p1);
p2++;
}
}
return res;
}
}
//作者:SweetTea
//链接:https://leetcode.cn/problems/maximum-distance-between-a-pair-of-values/solution/java-jing-dian-shuang-zhi-zhen-by-sweett-z06l/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
//自己的做法:
class Solution {
public:
int maxDistance(vector<int>& nums1, vector<int>& nums2) {
int left = 0;
int right = 0;
int maxd = 0;
while(left < nums1.size() && right < nums2.size()) {
if(left > right) right = left;//可以不出现
if(nums1[left] <= nums2[right]) {
if(right - left >= maxd) maxd = right - left;
right++;
}
else if(nums1[left] > nums2[right]) {
left++;
//right++;
}
}
return maxd;
}
};
复杂度分析
- O(n1+n2)最多遍历两个数组各一次。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-distance-between-a-pair-of-values
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
33. 搜索旋转排序数组(中等)
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -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
示例 3:
输入:nums = [1], target = 0
输出:-1
提示:
- 1 <= nums.length <= 5000
- -10000 <= nums[i] <= 10000
- nums 中的每个值都 独一无二
- 题目数据保证 nums 在预先未知的某个下标上进行了旋转
- -10000 <= target <= 10000
思路:
- 找到合适的区间 进行合适的分区来用二分;
- 和nums[0]进行比较,如果nums[middle] > nums[0] 则说明:在 0 - middle 区间内,是有序的,递增的;旋转点在middle - nums.size()-1 之间(nums[0] > nums[nums.size()-1])
- 进行分区:有序的,无序的
- nums[middle] >= nums[0] 有序:target在0 - middle之间二分查找
- nums[middle] >= nums[0] 无序:target在middle - nums.size()-1之间二分查找
- (nums[middle] < nums[0] 同理)
- 无序的一边可以理解为一个新的旋转数组
代码:
class Solution {
public:
int search(vector<int>& nums, int target) {
if (nums.size() == 0) return -1;
if (nums.size() == 1) return nums[0] == target ? 0 : -1;
int left = 0;
int right = nums.size() - 1;
while(left <= right) {
int middle = left + (right - left)/2;
if(nums[middle] == target) return middle;
if(nums[middle] >= nums[left]) {
if(nums[left] <= target && target < nums[middle]) right = middle - 1;
else left = middle + 1;
}
else if (nums[middle] < nums[right]) {
if(nums[middle] < target && target <= nums[right]) left = middle + 1;
else right = middle - 1;
}
}
return -1;
}
};
复杂度分析
- 二分查找时间复杂度:O(logn)
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
153. 寻找旋转排序数组中的最小值(中等)
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。
示例 2:
输入:nums = [4,5,6,7,0,1,2]
输出:0
解释:原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。
示例 3:
输入:nums = [11,13,15,17]
输出:11
解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
提示:
- n == nums.length
- 1 <= n <= 5000
- -5000 <= nums[i] <= 5000
- nums 中的所有整数 互不相同
- nums 原来是一个升序排序的数组,并进行了 1 至 n 次旋转
思路:
- 和nums[0]进行比较,如果nums[middle] > nums[0] 则说明:在 0 - middle 区间内,是有序的,递增的;(每次只旋转一个)
- 然后进行局部最小值查找(简单)
代码:
class Solution {
public:
int findMin(vector<int>& nums) {
if(nums.size() == 1) return nums[0] ;
int min = 5001;
int left = 0;
int right = nums.size() - 1;
while(left <= right) {
int middle = left + (right - left)/2;
if(nums[middle] >= nums[0]) {
if(nums[0] < min) {
min = nums[0];
}
left = middle + 1;
}
else if(nums[middle] < nums[0]) {
if(nums[middle] < min) {
min = nums[middle];
}
right = middle - 1;
}
}
return min;
}
};
复杂度分析
- 二分查找时间复杂度:O(logn)
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。