leetcode题目:
704. 二分查找(简单)
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-search
解答:
法一(二分查找法):
class Solution {
public:
int search(vector<int>& nums, int target)
{
int left = 0 ;
int mid= 0;
int right = nums.size()-1;
while(left <= right)
{
mid = left + (right - left) / 2;
if(nums[mid]== target)
{
return mid;
}
else if(nums[mid]> target)
{
right = mid-1;
}
else
{
left = mid+1;
}
}
return -1;
}
};
法二(利用STL简化代码):
class Solution {
public:
int search(vector<int>& nums, int target)
{
vector<int>::iterator pv=find(nums.begin(),nums.end(),target);
if(pv==nums.end())
return -1;
else
return pv-nums.begin();
}
};
35.搜索插入位置(简单)
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n)
的算法。
法一(暴力解法):严格来说不满足时间复杂度要求,因为这样复杂度是O(n);
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
//暴力解法
for(int i = 0;i < nums.size();i++)
{
if(nums[i]>=target)
return i;
}
return nums.size();
}
};
法二(二分查找法):重点在于理解目标值不在数组中的三种情况。
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)
return mid;
else if(nums[mid]>target)
right = mid-1;
else
left = mid+1;
}
return right+1;
}
34.在排序数组中查找元素的第一个和最后一个位置(中等)
法一(巧用STL):
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int>::iterator it = find(nums.begin(),nums.end(),target);
int Lborder = -1;
int Rborder = -1;
if(it != nums.end())
{
int num = count(nums.begin(),nums.end(),target);
int Lborder = it - nums.begin();
int Rborder = Lborder+num-1;
return {Lborder,Rborder};
}
return {Lborder,Rborder};
}
};
法二(二分查找法):
(对我个人来说挺难的,注意分情况讨论和分别寻找左右边界方法)
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int firstposition = findfirstposition(nums,target);
int lastposition = findlastposition(nums,target);
if(firstposition == -2 || lastposition == -2)
return {-1,-1};
else if(lastposition - firstposition > 1)
return {firstposition+1,lastposition-1};
else
return{-1,-1};
}
private:
int findfirstposition(vector<int>&nums,int target)
{
int left = 0;
int right = nums.size()-1;
int firstposition = -2;
while(left <= right)
{
int mid = left + (right - left)/2;
if(nums[mid] < target)
left = mid+1;
else
{
right = mid-1;
firstposition = right;
}
}
return firstposition;
}
int findlastposition(vector<int>&nums,int target)
{
int left = 0;
int right = nums.size()-1;
int lastposition = -2;
while(left <= right)
{
int mid = left +(right - left)/2;
if(nums[mid] > target)
right = mid-1;
else{
left = mid+1;
lastposition = left;
}
}
return lastposition;
}
};
69.x 的平方根(简单)
法一(投机取巧):
class Solution {
public:
int mySqrt(int x) {
if(x == 0)
return 0;
else
return pow(x,0.5);
}
};
法二(二分查找法):注意mid*mid可能是long long一定写明,不然溢出
class Solution {
public:
int mySqrt(int x) {
int left = 0;
int right = x;
int ret = -1;
while(left <= right)
{
int mid = left+(right-left)/2;
if((long long)mid*mid > x) //mid*mid可能是long 、long long 不加括号内容会运行超时
{
right = mid-1;
}
else if((long long)mid*mid == x)
{
return mid;
}
else
{
ret = mid;
left = mid+1;
}
}
return ret;
}
};
法三(牛顿迭代法): 注意判断条件
class Solution {
public:
int mySqrt(int x) {
if(x == 0)
return 0;
double C = x,x0 = x;
while(true)
{
double xi = 0.5*(x0+C/x0);
if(fabs(x0-xi) < 1e-7)
{
break;
}
x0 = xi;
}
return x0;
}
};
367.有效的完全平方数
二分查找法:
class Solution {
public:
bool isPerfectSquare(int num) {
//二分查找法
int left = 0;
int right = num;
while(left <= right)
{
int mid = left +(right-left)/2;
if((long long)mid*mid > num)
{
right = mid-1;
}
else if((long long)mid*mid == num)
{
return true;
}
else
left = mid+1;
}
return false;
}
};