题目一:搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(nums[mid] < target){
left = mid + 1;
}
else if(nums[mid] > target){
right = mid - 1;
}
else return mid;
}
return left;
}
};
题目二:x的平方根
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
class Solution {
public:
int mySqrt(int x) {
int left = 0, right = x;
while(left <= right){
int mid = left + (right - left) / 2;
if(long(mid) * mid > x){
right = mid - 1;
}
else if(long(mid) * mid < x){
left = mid + 1;
}
else return mid;
}
return right;
}
};
分析:题目一 给定一个数组,最终返回的就是 target 不属于数组时要插入的位置。二分法循环,如果找不到 target ,最终 left = right + 1 ,同时 left 左边的数都小于 target ,right 右边的数都大于 target 。
上面说到,left 左侧均为小于 target 的数,所以插入位置一定是在right + 1,即 left 。例如,nums = [1, 3, 5, 6],target = 2,最终一定是要插入到 1 3 之间,返回 1。
题目二 求舍去小数部分的 x 的算术平方根,与数组不同的是,最终返回的是一个数,而不是数组中的位置,所以与“搜索插入位置”这题相比,最终返回的应该是 小于目标值的最大的数。目标值就是 x 的真实算术平方根。如 x = 8,则目标值为 2.82842…
同时要注意,涉及到乘法计算时,要转换类型,否则可能越界:
if(long(mid) * mid > x) right = mid - 1;
else if(long(mid) * mid < x) left = mid + 1;