C/C++编程刷题分享—二分法查找

✅作者简介:嵌入式领域新星创作者,博客专家
✨个人主页:咸鱼弟
🔥系列专栏:剑指offer专栏

目录

1.题目描述

2.解题思路

2.1.提取题目信息     

2.2.知识点——二分法

3.参考代码

4.复杂度分析


1.题目描述

2.解题思路

2.1.提取题目信息     

  • 给定一个元素升序的、无重复数字的整型数组 nums 和一个目标值 target
  • 找到目标值的下标
  • 如果找不到返回-1

2.2.知识点——二分法

分治即“分而治之”,“分”指的是将一个大而复杂的问题划分成多个性质相同但是规模更小的子问题,子问题继续按照这样划分,直到问题可以被轻易解决;“治”指的是将子问题单独进行处理。经过分治后的子问题,需要将解进行合并才能得到原问题的解,因此整个分治过程经常用递归来实现。

思路:

本来我们可以遍历数组直接查找,每次检查当前元素是不是要找的值。

for(int i = 0; i < nums.length; i++)
{
    if(nums[i] == target)
        return i;
}

但是这样这个有序的数组我们就没有完全利用起来。我们想想,若是目标值比较小,肯定在前半区间,若是目标值比较大,肯定在后半区间,怎么评价大小?我们可以用中点值作为一个标杆,将整个数组分为两个区间,目标值与中点值比较就能知道它会在哪个区间,这就是分治的思维。

具体做法:

  • step 1:从数组首尾开始,每次取中点值。
  • step 2:如果中间值等于目标即找到了,可返回下标,如果中点值大于目标,说明中点以后的都大于目标,因此目标在中点左半区间,如果中点值小于目标,则相反。
  • step 3:根据比较进入对应的区间,直到区间左右端相遇,意味着没有找到。

图示:

3.参考代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l = 0;
        int r = nums.size() - 1;
        //从数组首尾开始,直到二者相遇
        while(l <= r){ 
            //每次检查中点的值
            int m = (l + r) / 2; 
            if(nums[m] == target)
                return m;
            //进入左的区间
            if(nums[m] > target) 
                r = m - 1;
            //进入右区间
            else 
                l = m + 1;
        }
        //未找到
        return -1; 
    }
};

4.复杂度分析

  • 时间复杂度:O(log2n)O(log_2n)O(log2​n),对长度为nnn的数组进行二分,最坏情况就是取2的对数
  • 空间复杂度:O(1)O(1)O(1),常数级变量,无额外辅助空间

二分法查找是一种基本的查找方法,需要大家掌握其实现原理。 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是C++实现顺序查找算法二分法查找算法的示例代码: ```c++ #include <iostream> #include <vector> #include <algorithm> using namespace std; // 顺序查找算法 int seqSearch(vector<int>& nums, int target) { for (int i = 0; i < nums.size(); i++) { if (nums[i] == target) { return i; } } return -1; // 查找失败 } // 二分法查找算法 int binarySearch(vector<int>& nums, int target) { int left = 0, right = nums.size() - 1; while (left <= right) { int mid = (left + right) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; // 查找失败 } int main() { vector<int> nums = {3, 5, 2, 8, 4, 7, 1, 6}; sort(nums.begin(), nums.end()); // 二分法查找算法需要有序表 int target = 4; int index1 = seqSearch(nums, target); // 调用顺序查找算法 int index2 = binarySearch(nums, target); // 调用二分法查找算法 if (index1 != -1) { cout << "顺序查找成功,目标元素下标为:" << index1 << endl; } else { cout << "顺序查找失败,未找到目标元素" << endl; } if (index2 != -1) { cout << "二分法查找成功,目标元素下标为:" << index2 << endl; } else { cout << "二分法查找失败,未找到目标元素" << endl; } return 0; } ``` 以上代码中,我们使用了STL中的vector容器来存储顺序表元素,并使用sort函数对其进行排序,以便二分法查找算法能够正确执行。在main函数中,我们分别调用了顺序查找算法二分法查找算法,查找目标元素的值为4。最后,根据返回的下标值,输出查找结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咸鱼弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值