一、数组部分——二分查找

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;
    }
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值