C++实现二分查找(力扣题目704)

题目要求:给定一个n个元素的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1

示例

输入: nums= [-1,0,3,5,9,12]
target= 9
输出: 4
解释: 9 出现在 nums中并且下标为 4
输入: nums= [-1,0,3,5,9,12], target= 2
输出: -1
解释: 2 不存在 nums中因此返回 -1

拿到这个题目的第一想法就是逐个遍历,把数组中的每一个元素都和target进行比较,根据比较的结果按要求返回对应的值。如果数组中下标为i的元素等于target,就返回i;如果把数组全部遍历了一遍仍然没有找见target,就返回-1;

class Solution {
public:
    int search(vector<int>& nums, int target) {
        for(int i=0;i<nums.size();++i)
        {
            if(nums[i]==target)
            {
                return i;
            }
        }
        return -1 ;
    }
};

我相信大部分没有学过算法的人拿到这道题的第一想法都跟我一样,用遍历匹配的方法来做。

当然了这样能做出来,而且得到的结果肯定是正确的,但是假如数组中的元素特别多,有100万个元素,而恰好我们要找的target是第999999个,这样用遍历匹配的方法就会非常耗时。

其实我们可以改变思路让代码执行起来更简单一些,所以呢就得想另外一种方法来求解,这个方法就是二分法。 

升序数组nums[i]中查找目标值target,可以肯定的是,对于某一特定值 i 和 target :

  • if(nums[i]==target),则 i 就是我们需要的
  • if(num[i]<target),则target只可能在 i 的右侧
  • if(num[i]>target),则target只可能在 i 的左侧

基于上述基本事实,我们可以在有序数组中使用二分查找法寻找target。具体做法是,定义查找的范围是[left,right],初始查找范围是整个数组。每次取查找范围的中点mid,比较nums[mid]和target的大小,如果相等则mid为需要的下标,如果不相等则根据nums[mid]和target的大小关系将查找范围缩小一半。二分查找的条件是查找范围不为空,即left<=right。如果target在数组中,二分查找就可以找到target,并返回target在数组中的下标。如果target不在数组中,就返回-1。

具体的代码如下

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0,right=nums.size()-1;
        while(left<=right)
        {
            int mid=(right-left)/2+left;
            if(nums[mid]==target)
            {
                return mid;
            }
            else if(nums[mid]>target)
            {
                right=mid-1;
            }
            else
            {
                left=mid+1;
            }
        }
        return -1;
    }
};

我们把它放在vs里面测试一下

#include<iostream>
#include<vector>
using namespace std;

int search(vector<int>& nums, int target) {
    int left = 0, right = nums.size() - 1;
        while (left <= right)
        {
            int mid = (right - left) / 2 + left;
            if (nums[mid] == target)
            {
                return mid;
            }
            else if (nums[mid] > target)
            {
                right = mid - 1;
            }
            else
            {
                left = mid + 1;
            }
        }
        return -1;
 }

int main()
{
    vector<int> vec{ 1,4,5,7,11,14,18 };
    cout << "vec: ";
    for (auto c : vec)
    {
        cout << c << " ";
    }
    cout << endl;
    /*int tar = 5;*/
    int tar = 2;
    int i=search(vec, tar);
    if (i >= 0)
        cout << tar<<" index is " << i << endl;
    else
        cout << tar<<" not found" << endl;
}

分别测试两个数,结果如下: 

猜你喜欢

转载自blog.csdn.net/yangSHU21/article/details/130567061