class Solution { public: int search(vector& nums, int target) { int left = 0, right = nums.size() - 1; while(left <= right){ int mid = (right - left) / 2 + left; int num = nums[mid]; if (num == target) { return mid; } else if (num > target) { right = mid - 1; } else { left = mid + 1; } } return -1; } };
第一题没什么细节,用笔在纸上画一下模拟一下即可
这一道题相对其他题比较抽象,具体体现在其最后一个位置不好找,因为在编译的时候,计算mid时系统会自动向下取整,因此在处理左端点时可以向下取整得到,处理又端点时需要向上取整,同时要注意数据的溢出,这里是如何处理的。
class Solution { public: vectorsearchRange(vector & nums, int target) { if (nums.size() == 0) return{ -1,-1 }; int begin = 0; int left = 0, right = nums.size() - 1, mid; while (left < right) { mid = left + (right - left) / 2; if (nums[mid] < target) left = mid + 1; else right = mid; } if (target != nums[right]) return{ -1,-1 }; else begin = left; left = 0, right = nums.size() - 1; while (left < right) { mid = left + (right - left + 1) / 2; if (nums[mid] <= target) left = mid; else right = mid-1; } return{ begin,right }; } };
我绝得这个题最关键的步骤就是,nums[mid]与target是否取等,在求开始位置的时候,不用取等,原因是else成立条件为>=那么right所指向的未必是最右边的那个元素,因为可能有重复元素,对于求最后位置时,else条件为>的目的是,使得right所指向的目标元素为最后的位置。
class Solution { public: int searchInsert(vector& nums, int target) { int n = nums.size(); int l=0,r=n-1; while(l<=r){ int mid=l+(r-l)/2; if(nums[mid]
- 判断中间位置的值 nums[mid] 与目标值 target 的大小关系:
- 若 nums[mid] < target,说明目标值在右半部分,将 l 更新为 mid+1。
- 若 nums[mid] >= target,说明目标值在左半部分或者等于中间值,将 r 更新为 mid-1。
- 循环结束后,返回 l,即为目标值在数组中的插入位置
第四题:
整数平方根最小为1,最大为本身,因此左指针指在1,右指针指在r,防止mid*mid的值溢出,将数据类型设为long long 类型
在这个平方根求解算法中,向上取整(即计算中点时使用的 mid = l + (r - l + 1) / 2 而不是 mid = l + (r - l) / 2)的主要原因是为了确保二分查找过程能够正确地收敛,特别是在处理左右边界相邻但还未找到确切平方根整数值的情况下。
这个细节主要影响的是当左边界(l)和右边界(r)相邻时的行为。常规的二分查找中点计算(向下取整)可能会导致在某些情况下循环不能正确终止,进而错过正确答案。具体到这个问题:
第五题:
class Solution { public: int peakIndexInMountainArray(vector& arr) { int l=1,r=arr.size()-2,mid; while(l 山脉即大于左右两边的山,暴力也可求解
class Solution { public: int peakIndexInMountainArray(vector& arr) { int n = arr.size(); // 遍历数组内每⼀个元素,直到找到峰顶 for (int i = 1; i < n - 1; i++) // 峰顶满⾜的条件 if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1]) return i; // 为了处理 oj 需要控制所有路径都有返回值 return -1; } }