704 二分查找
如果把相等的情况放在第一个判断,Leetcode第16个测试用例会超时。
class Solution {
public:
int search(vector<int>& nums, int target) {
int l=0,r=nums.size()-1;
while(l<=r){// 条件不能为(l<r),当nums长度为1且该元素与target相等时,会跳过循环返回-1
int m=(l+r)/2; // m=l+(r-l)/2可以防止溢出
if(nums[m]>target){// target在nums[m]左边
r=m-1;
}else if(nums[m]==target){
return m;
}else{// target在nums[m]右边
l=m+1;
}
}
return -1;
}
};
34 在排序数组中查找元素的第一个和最后一个位置
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
// 题目理解错误,下标可以一样,即target出现一次
int l=0,r=nums.size()-1;
while(l<=r){// 条件不能为l<r,会跳过长度为1的数组
int m=l+(r-l)/2;
if(target<nums[m]){
r=m-1;
}else if(target>nums[m]){
l=m+1;
}else{//target==nums[m],由于target连续,用while循环把左右指针移动至两端的target处
while(nums[l]!=target){
l++;
}
while(nums[r]!=target){
r--;
}
return {l,r};
}
}
return {-1,-1};
}
};
162 寻找峰值
class Solution {
public:
int findPeakElement(vector<int>& nums) {
// 寻找max
// return max_element(nums.begin(),nums.end())-nums.begin();
if (nums.size() == 1) {
return 0;
}
if (nums.size() == 2) {
return (nums[0] < nums[1]) ? 1 : 0;
}
int l = 0, r = nums.size() - 1;
while (l < r) {
int m = (l+r) / 2;
// 写成 int m= l+(r-l)/2; 时,leetcode测试用例[1,2,3,1]会越界
if (nums[m] > nums[m + 1]) {//往[l,m]继续找
r = m;
}
else {//往[m+1,r]继续找
l = m + 1;
}
}
return l;
}
};
74 搜索二维矩阵
先判断target是否位于矩阵包含的区间中,再用二分查找的方法判断在哪一行,最后进行二分查找。
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0, r = nums.size() - 1;
while (l <= r) {// 条件不能为(l<r),当nums长度为1且该元素与target相等时,会跳过循环返回-1
int m = (l + r) / 2;
if (nums[m] > target) {// target在nums[m]左边
r = m - 1;
}
else if (nums[m] == target) {
return m;
}
else {// target在nums[m]右边
l = m + 1;
}
}
return -1;
}
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m = matrix.size(), n = matrix[0].size();
if ((matrix[m - 1][n - 1] < target) || (matrix[0][0] > target)) {
return false;
}
int l = 0, r = m - 1;
int target_column = 0;//行定位
while (l <= r) {
// int m = l + (r - 1) / 2;//z这里第二个字母l写成了数字1,报错了
//Line 1037: Char 9: runtime error: reference binding to misaligned address 0xbebebebebebebebe for type 'int', which requires 4 byte alignment (stl_vector.h)
int mid = l + (r - l) / 2;
if (matrix[mid][0] > target) {
r = mid - 1;
}
else if ((matrix[mid][0] <= target) && (target <= matrix[mid][n - 1])) {
target_column = mid;
break;
}
else {
l = mid + 1;
}
}
int target_row = search(matrix[target_column], target);//二分查找
return (target_row == -1) ? false : true;
}
};
153 寻找旋转排序数组中的最小值
class Solution {
public:
int findMin(vector<int>& nums) {
if(nums.size()==1){
return nums[0];
}
int l=1,r=nums.size()-1;//l=1是因为下面的while循环要用到nums[m-1],防止数组越界
//旋转n次的数组,即原数组,元素单调递增
if(nums[0]<nums[r]&&nums[0]<nums[1]){
return nums[0];
}
//旋转[1,n-1]次的数组
while(l<=r){
int m=l+(r-l)/2;
if(nums[m-1]>nums[m]){//旋转[1,n-1]次的数组,一定会出现一次降序
return nums[m];
}
if(nums[m-1]<nums[m]&&nums[0]<nums[m]){
l=m+1;
}else{
r=m;
}
}
return 0;
}
};
15.三数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
if ((nums.size() <= 2)) {
return ans;
}
sort(nums.begin(), nums.end());
int n = nums.size();
for (int i = 0; i < n - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) { //跳过连续相等的值
continue;
}
int left = i + 1;
int right = n - 1;
while (left < right) {
if (nums[i] + nums[left] + nums[right] == 0) {
ans.push_back({nums[i], nums[left], nums[right]});
while (left < right && nums[left] == nums[left + 1])//跳过连续相等的值
left++;
while (left < right && nums[right] == nums[right - 1])//跳过连续相等的值
right--;
left++;//此时nums[left]与原来的不相等,nums[right]同理
right--;
} else if (nums[i] + nums[left] + nums[right] < 0) {
left++;
} else {
right--;
}
}
}
return ans;
}
};