二分法
代码随想录之二分法
704.二分法查找
1.给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
分析:如给定一个数组{1,2,3,4,5,6},给定一个target =3,进行查找
方法一:暴力解法,利用for循环进行遍历
class Solution { public int[] searchRange(int[] nums, int target) { for(int i =0; i < nums.length; i++){ if (nums[i] == target){ return i;} else {return -1;} } } }
方法二:二分查找
第一种 左闭右闭[left,right]
class Solution {
public int search(int[] nums, int target) {
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
return -1;
}
}
左闭右闭时,while( left < = right) 当left = right 有意义 。
int mid = left + (right - left) / 2 的作用是:防止数据溢出。
当 nums[mid]>target 说明target位于mid的左边,right = mid - 1;区间变为[left,mid - 1]
当 nums[mid]<target 说明target位于mid的右边,left = mid + 1;区间变为[mid + 1,right]
第二种:左闭右开[left,right)
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length;
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid;
}
return -1;
}
}
当 nums[mid]>target 说明target位于mid的左边,right = mid - 1;区间变为[left,mid )
当 nums[mid]<target 说明target位于mid的右边,left = mid + 1;区间变为[mid + 1,right)
35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
有四种情况,target小于nums[0]在数组前,target大于nums[0]小于nums[nums.length-1]但没有对应值,target在范围内有对应值,target大于nums[nums.length-1]
class Solution { public int searchInsert(int[] nums, int target) { int left = 0; int right = nums.length - 1; while(left <= right){ int mid = left + (right - left) / 2; if(nums[mid] == target){ return mid; } else if(nums[mid] > target){ right = mid - 1; } else if(nums[mid] < target){ left = mid + 1; } } return right + 1; } }
return right +1的原因:当最后一次进行时 left = right =mid。如果(nums[mid] > target) 说明位置应该放在mid(也可以说是left或right)这个地方,但是后面进行了right =mid -1;则此时的位置应该是left或者right+1;
如果(nums[mid] < target) ,说明结点在mid后面即mid+1处,后面对right也应该+1,则此时位置可以用left或者right+1表示。
69.x的平方根
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
class Solution { public int mySqrt(int x) { int left = 0; int right = x;
int temp = 0; while (left <= right){ int mid = left + (right - left) / 2; long square = (long) mid * mid; if (square > x){ right = mid - 1; } else (square <= x){ temp = mid;
left = left + 1; } } return temp; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理