今天做的题目是有关二分查找的:
1.二分查找基本题目(力扣704):
在以前的基础上,考虑给定值比数组中最小的小或最大的大的情况。
public int search(int[] nums, int target) {
int low = 0;
int high = nums.length-1;
int result;
if((target<nums[0])||(target>nums[nums.length-1]))
return -1;
while ((nums[(low+high)/2] != target)&&(low<=high))
{
if(nums[(low+high)/2]<target){
low = (low+high)/2+1;
}
else
high = (low+high)/2-1;
}
if (low>high)
return -1;
else
return (low+high)/2;
}
2.二分查找+插入位置(力扣35):
题目要求在O(logn)的时间复杂度内完成,因此考虑二叉树结构,采用二分查找;若不在则返回插入位置,若存在则插到相同元素之前。
public int searchInsert(int[] nums, int target) {
if(target<nums[0])
return 0;
if(target>nums[nums.length-1])
return nums.length;
int low = 0;
int high = nums.length-1;
while ((nums[(low+high)/2])!=target&&(low<=high))
{
if (nums[(low+high)/2]<target)
low = (low+high)/2+1;
else
high = (low+high)/2-1;
}
//根据存在不存在,分别返回
if(low>high)
return (low+high)/2+1;
else
return (low+high)/2;
}
3.二分查找提升题(力扣34)
题目同样要求在O(logn)的时间复杂度内完成,继续选择二叉树结构,由于数组升序,选择二分查找。要注意数组越界问题。
public int[] searchRange(int[] nums, int target) {
// if(nums.length == 0)
// return new int[]{-1,-1};
if((nums.length == 0)||(target<nums[0])||(target>nums[nums.length-1]))
return new int[]{-1,-1};
int low = 0;
int high = nums.length-1;
int i,j;//用来指向目标值在数组中的开始和结束位置
while (((nums[(low+high)/2])!=target) && (low<=high)){
if(nums[(low+high)/2] < target)
low = (low+high)/2+1;
else
high = (low+high)/2-1;
}
if (low>high)
return new int[]{-1,-1};
else {
i = (low+high)/2;
j = (low+high)/2;
while ((i>0)&&(nums[i-1] == target))
i--;
while ((j<nums.length-1)&&(nums[j+1] == target))
j++;
}
return new int[]{i,j};
}
4.二分查找应用题,x的平方根(力扣69)
当x大于1时,其平方根小于等于x/2,根据此,在1到x/2的区间内查找其平方根,属于二分查找的应用。同时避免数过大,将乘法变为除法,也要避免除以0。
public int mySqrt(int x) {
if(x==0||x==1)
return x;
//low设置为1防止下面mid==0造成除0
int low = 1;
//当x>1时,其平方根小于等于这个数的一半
int high = x/2;
int mid = (low+high)/2;
//防止mid的平方大于2^31-1,循环中采用除法
while (low<=high){
if(mid == x/mid)
return mid;
else if(mid>x/mid){
high = mid-1;
mid = (low+high)/2;
}
else{
low = mid+1;
mid = (low+high)/2;
}
}
return mid;
}
5.二分查找应用题,跟完全平方有关(力扣367)
这里注意int类型的数运算完会向下取整(如2 == 5/2 是成立的),因此将mid定义为double类型(2.0 == 5/2.0 是不成立的)
public boolean isPerfectSquare(int num) {
if(num == 0 || num == 1)
return true;
int low = 1;
int high = num/2;
double mid = (low+high)>>1;
while (low<=high){
if(mid == num/mid)
return true;
else if(mid < num/mid)
{
low = (int)mid+1;
mid = (low+high)>>1;
}
else {
high = (int)mid-1;
mid = (low+high)>>1;
}
}
return false;
}








