1. 二分查找
704. 二分查找
https://leetcode.cn/problems/binary-search/
给定一个
n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果target存在返回下标,否则返回-1。你必须编写一个具有
O(log n)时间复杂度的算法。
cppclass Solution { public: int search(vector<int>& nums, int target) { int left=0,right=nums.size()-1; while(left<=right) { int order=left+(right-left)/2; if(target>nums[order]) left=order+1; else if(target<nums[order]) right=order-1; else return order; } return -1; } };最基础的写法,但有时会因为特殊情况,导致效率约等于暴力算法。
2. x的平方根
69. x 的平方根
https://leetcode.cn/problems/sqrtx/
给你一个非负整数
x,计算并返回x的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如
pow(x, 0.5)或者x ** 0.5。
cppclass Solution { public: int mySqrt(int x) { long long left=0,right=x; while(left<right) { long long mid=left+(right-left+1)/2; if(mid*mid<=x) left=mid; else right=mid-1; } return left; } };优化写法,查找0~X区间,返回左端。
3. 搜索插入位置
LCR 068. 搜索插入位置
https://leetcode.cn/problems/N6YdxV/
给定一个排序的整数数组
nums和一个整数目标值target,请在数组中找到target,并返回其下标。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为
O(log n)的算法。
cppclass Solution { public: int searchInsert(vector<int>& nums, int target) { int left=0,right=nums.size()-1; while(left<right) { int mid=left+(right-left +1 )/2; if(nums[mid]<=target) left=mid; else right=mid-1;//出现减号,上面mid中+1 } if(nums[left]<target) return left+1; else return left; } };注意:写法格式
4. 山脉数组的峰顶索引
LCR 069. 山脉数组的峰顶索引
https://leetcode.cn/problems/B1IidL/
符合下列属性的数组
arr称为 山峰数组(山脉数组) :
arr.length >= 3- 存在
i(0 < i < arr.length - 1)使得:
arr[0] < arr[1] < ... arr[i-1] < arr[i]arr[i] > arr[i+1] > ... > arr[arr.length - 1]给定由整数组成的山峰数组
arr,返回任何满足arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1]的下标i,即山峰顶部。
cppclass Solution { public: int peakIndexInMountainArray(vector<int>& arr) { int left=0,right=arr.size()-1; while(left<right) { int mid=left+(right-left+1)/2; if(arr[mid]>=arr[mid-1]) left=mid; else right=mid-1; } return left; } };
5. 丢失的数字
268. 丢失的数字
https://leetcode.cn/problems/missing-number/
给定一个包含
[0, n]中n个数的数组nums,找出[0, n]这个范围内没有出现在数组中的那个数
cppclass Solution { public: int missingNumber(vector<int>& nums) { sort(nums.begin(),nums.end()); int left=0,right=nums.size()-1; while(left<right) { int mid=left+(right-left+1)/2; if(nums[mid]==mid) left=mid; else right=mid-1; } if(nums[0]!=0) return 0; return left+1; } };异或法:
cppclass Solution { public: int missingNumber(vector<int>& nums) { int sum=0; for(auto e:nums)sum^=e; for(int i=0;i<=nums.size();i++)sum^=i; return sum; } };
⭐6. 在排序数组中查找元素的第一个和最后一个位置
给你一个按照非递减顺序排列的整数数组
nums,和一个目标值target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值
target,返回[-1, -1]。你必须设计并实现时间复杂度为
O(log n)的算法解决此问题
cppclass Solution { public: vector<int> searchRange(vector<int>& nums, int target) { if(nums.size()==0) return {-1,-1}; int left=0,right=nums.size()-1; vector<int> result; //二分左端点; while(left<right) { int mid=left+(right-left)/2; if(nums[mid]<target) left=mid+1; else right=mid; } if(nums[left]!=target)return {-1,-1}; else result.push_back(left); //二分右端点 right=nums.size()-1; while(left<right) { int mid=left+(right-left+1)/2; if(nums[mid]<=target) left=mid; else right=mid-1; } result.push_back(right); return result; } };注意:查找左端和右端的写法细节。
库函数方法:
cppclass Solution { public: vector<int> searchRange(vector<int>& nums, int target) { int start = ranges::lower_bound(nums, target) - nums.begin(); if (start == nums.size() || nums[start] != target) { return {-1, -1}; } int end = ranges::upper_bound(nums, target) - nums.begin() - 1; return {start, end}; } };
7. 寻找旋转 排序数组中的最小值
153. 寻找旋转排序数组中的最小值
https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/
已知一个长度为
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)的算法解决此问题
cppclass Solution { public: int findMin(vector<int>& arr) { int left=0,right=arr.size()-1; while(left<right) { int mid=left+(right-left)/2; if(arr[mid]>arr[right]) left=mid+1; else right=mid; } return arr[left]; } };注意:逻辑很重要。
8. 搜索二维矩阵
74. 搜索二维矩阵
https://leetcode.cn/problems/search-a-2d-matrix/
给你一个满足下述两条属性的
m x n整数矩阵:
- 每行中的整数从左到右按非严格递增顺序排列。
- 每行的第一个整数大于前一行的最后一个整数。
给你一个整数
target,如果target在矩阵中,返回true;否则,返回false。
cppclass Solution { public: bool searchMatrix(vector<vector<int>>& matrix, int target) { int left=0,right=matrix[0].size()-1,floor=0; while(left<right&&floor<matrix.size()) { while(floor<matrix.size()&&target>matrix[floor][right]) floor++; if(floor==matrix.size()) return false; int mid=left+(right-left+1)/2; if(matrix[floor][mid]<=target) left=mid; else right=mid-1; } while(floor<matrix.size()&&target>matrix[floor][right]) floor++; if(floor==matrix.size()) return false; if(matrix[floor][left]==target) return true; else return false; } };


