06-C++ 基本算法 - 二分法

这篇具有很好参考价值的文章主要介绍了06-C++ 基本算法 - 二分法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

06-C++ 基本算法 - 二分法,c++,算法,开发语言

📖 前言

在这个笔记中,我们将介绍二分法这种基本的算法思想,以及它在 C++ 中的应用。我们将从一个小游戏猜数字开始,通过这个案例来引出二分法的概念。然后我们将详细讲解什么是二分法以及它的套路和应用。最后,我们还会介绍 C++ STL 中的二分查找函数。让我们一起来探索吧!

🎯 什么是二分法

二分法是一种高效的搜索算法,通过将搜索范围不断缩小一半来快速找到目标值。它适用于有序数组或有序区间中查找特定元素的问题。二分法的基本思想是通过比较中间值与目标值的大小关系,来确定目标值可能存在的那一半区间,然后在该区间内继续查找。

🎮 小游戏猜数字

让我们通过一个小游戏来理解二分法的基本思想。假设有一个整数范围为 1 到 100,你需要猜一个隐藏的数字。每次猜测后,系统会告诉你猜的数字是大了还是小了,直到猜中为止。

06-C++ 基本算法 - 二分法,c++,算法,开发语言

这个小游戏的思路就是使用二分法来快速定位目标数字的范围。每次猜测时,将当前范围的中间数字与目标数字进行比较,根据比较结果来调整范围。通过不断缩小范围,最终可以找到目标数字。

🌟 二分法的套路

二分法有一些常见的套路和应用场景,我们将逐个介绍它们。

3.1 整数的二分

整数的二分是二分法的一种常见应用。我们以两个案例来说明整数的二分应用。

3.1.1 案例1: 力扣704. 二分查找

给定一个升序排列的整数数组 nums 和一个目标值 target,请你实现二分查找算法,如果目标值存在于数组中,则返回其索引,否则返回 -1。

示例代码:

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

int binarySearch(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) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}

int main() {
    vector<int> nums = {1, 3, 5, 7, 9, 11};
    int target = 7;
    int result = binarySearch(nums, target);
    if (result != -1) {
        cout << "目标值 " << target << " 在数组中的索引为 " << result << endl;
    } else {
        cout << "目标值 " << target << " 不存在于数组中" << endl;
    }
    return 0;
}

运行结果:

目标值 7 在数组中的索引为 3

在上述代码中,我们使用二分法实现了查找目标值在有序数组中的索引。通过不断调整搜索范围的左右边界,并根据中间值与目标值的比较结果来确定下一步的搜索方向,最终可以找到目标值的索引。

3.1.2 案例2: 力扣350. 两个数组的交集 II

给定两个整数数组 nums1nums2,请你返回它们的交集。结果中每个元素的出现次数应与元素在两个数组中出现的次数一致(如果次数不一致,则取较小的次数)。结果不考虑顺序。

示例代码:

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

vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
    unordered_map<int, int> counter;
    for (int num : nums1) {
        counter[num]++;
    }
    
    vector<int> result;
    for (int num : nums2) {
        if (counter[num] > 0) {
            result.push_back(num);
            counter[num]--;
        }
    }
    
    return result;
}

int main() {
    vector<int> nums1 = {1, 2, 2, 1};
    vector<int> nums2 = {2, 2};
    vector<int> result = intersect(nums1, nums2);
    
    cout << "两个数组的交集为:";
    for (int num : result) {
        cout << num << " ";
    }
    cout << endl;
    
    return 0;
}

运行结果:

两个数组的交集为:2 2

在上述代码中,我们使用哈希表记录了 nums1 中每个元素的出现次数,并通过遍历 nums2 找到与之对应的交集元素。通过减少交集元素的出现次数,最终可以得到交集的结果。

3.2 实数的二分

除了整数的二分,实数的二分也是二分法的一种应用。在实数的二分中,我们需要考虑精度问题,因为实数在计算机中无法表示为精确的值。下面是一个案例来说明实数的二分应用。

案例: 计算平方根

给定一个非负实数 x,要

求计算它的平方根并返回。我们可以使用二分法来逼近平方根的值,直到达到所需的精度。

示例代码:

#include <iostream>
using namespace std;

double sqrt(double x, double precision) {
    if (x < 0) {
        return -1; // 输入错误,返回 -1
    }
    
    double left = 0;
    double right = x;
    double mid;
    
    while (right - left > precision) {
        mid = left + (right - left) / 2;
        if (mid * mid <= x) {
            left = mid;
        } else {
            right = mid;
        }
    }
    
    return left;
}

int main() {
    double x = 16;
    double precision = 0.0001;
    double result = sqrt(x, precision);
    
    cout << "输入的数:" << x << endl;
    cout << "计算得到的平方根:" << result << endl;
    
    return 0;
}

运行结果:

输入的数:16
计算得到的平方根:4

在上述代码中,我们通过二分法逼近平方根的值,直到所达到的精度小于指定的 precision。通过不断调整搜索范围的左右边界,最终可以得到近似的平方根值。

💡 STL 二分查找

除了手动实现二分法算法,C++ STL(标准模板库)中也提供了二分查找的函数。这些函数包括 lower_bound()upper_bound(),它们可以方便地应用于有序容器中。

4.1 lower_bound()

lower_bound() 函数用于在有序容器中查找第一个大于或等于给定值的元素的迭代器。

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

int main() {
    vector<int> nums = {1, 3, 5, 7, 9};
    int target = 4;
    auto it = lower_bound(nums.begin(), nums.end(), target);
    
    if (it != nums.end()) {
        cout << "第一个大于或等于目标值的元素为:" << *it << endl;
    } else {
        cout << "没有找到满足条件的元素" << endl;
    }
    
    return 0;
}

运行结果:

第一个大于或等于目标值的元素为:5

在上述代码中,我们使用 lower_bound() 函数在有序容器 nums 中查找第一个大于或等于目标值 target 的元素。函数返回一个迭代器,指向满足条件的元素。

4.2 upper_bound()

upper_bound() 函数用于在有序容器中查找第一个大于给定值的元素的迭代器。

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

int main() {
    vector<int> nums = {1, 3, 5, 7, 9};
    int target = 4;
    auto it = upper_bound(nums.begin(), nums.end(), target);
    
    if (it != nums.end()) {
        cout << "第一个大于目标值的元素为:" << *it << endl;
    } else {
        cout << "没有找到满足条件的元素" << endl;
    }
    
    return 0;
}

运行结果:

第一个大于目标值的元素为:5

在上述代码中,我们使用 upper_bound() 函数在有序容器 nums 中查找第一个大于目标值 target 的元素。函数返回一个迭代器,指向满足条件的元素。

📚 总结

在本篇笔记中,我们学习了二分法这种基本的算法思想,并在 C++ 中通过案例和代码进行了详细讲解。我们了解了二分法的套路和应用场景,包括整数的二分和实数的二分。此外,我们还介绍了 C++ STL 中的二分查找函数 lower_bound()upper_bound(),它们可以方便地应用于有序容器中。希望通过本篇笔记的学习,你对二分法有了更深入的理解,并能够熟练应用于解决问题。祝你在算法学习的道路上越走越远!

本篇笔记内容主要参考了《算法竞赛进阶指南》和 LeetCode 等相关资源。

⭐️希望本篇文章对你有所帮助。

⭐️如果你有任何问题或疑惑,请随时向提问。

⭐️感谢阅读!文章来源地址https://www.toymoban.com/news/detail-592472.html

到了这里,关于06-C++ 基本算法 - 二分法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构和算法之二分法查找

    二分法查找,也称作 二分查找 或 折半查找 ,是一种在有序数组中快速查找特定元素的算法。它采用分治法思想,通过将问题划分为规模更小的子问题,并且通过对子问题的查找来解决原问题。 二分法查找的思路是不断地将数组一分为二,然后判断目标值在哪一部分,进而

    2024年02月09日
    浏览(48)
  • 算法刷题营【Day1】:: 704.二分查找:二分法详谈与相关刷题

    本内容是笔者结合《代码随想录》总结所得,记录学习过程,分享知识! 目录: 1. 开篇例题:704. 二分查找 2. 题解参考(模板写法) - - 2.1 方法一:左闭右闭写法 - - 2.2 方法二:左闭右开写法 3. 模板解释:左闭右闭 - - 3.1 区间划定 - - 3.2 left 、right 移动问题 - - 3.3 循环条件

    2024年02月04日
    浏览(46)
  • 二分法相关使用

    在线OJ:704. 二分查找 有序数组下的二分思路如下: 由于这里是有序数组, 我们可以可以先得到中点位置, 中点可以把数组分为左右两边; 如果中点位置的值等于目标值, 直接返回中点位置; 如果中点位置的值小于目标值, 则去数组中点左侧按同样的方式查找; 如果中点位置的值大

    2024年02月07日
    浏览(44)
  • 二分法MATLAB代码

    本质是通过不断进行区间压缩来获取函数零点。 二分法的终止条件:区间长度小于等于精度要求 。 流程: 如下图所示:

    2024年02月05日
    浏览(47)
  • 二分法简单题

    2024年01月24日
    浏览(55)
  • 初探二分法

    智能化校园:深入探讨云端管理系统设计与实现(一) 智能化校园:深入探讨云端管理系统设计与实现(二) 题目:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 提示: 你可以

    2024年01月25日
    浏览(59)
  • 【二分查找】一文带你掌握二分法 (附万能模板)

    一、简介 哪怕没有学过编程的同学,也许不知道二分法这个名字,但也一定接触过它的核心思想。不了解的同学也没关系,我用一句话就能概括出它的精髓: 将一个区间一分为二,每次都舍弃其中的一部分。 二分法能够极大地降低我们在解决问题时的时间复杂度。假如你要

    2024年01月19日
    浏览(58)
  • 【剑指Offer】二分法例题

    链表是数据结构中重要的一个章节,他的重要性也不言而喻,在未来不管是笔试还是面试都会遇到这类的题目,所以接下来我就会把一些链表的常考的题目全部整理出来供大家学习指正。 题目链接 描述: 给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包

    2023年04月13日
    浏览(46)
  • 非线性方程二分法

    优点:算法直观、简单、总能保证收敛;局限:收敛速度慢、一般不单独用它求根,仅为了获取根的粗略近似 设 f ( x ) f(x) f ( x ) 在 [ a , b ] [a,b] [ a , b ] 上连续、严格单调、满足条件 f ( a ) f ( b ) 0 f(a)f(b)0 f ( a ) f ( b ) 0 则在区间 [ a , b ] [a,b] [ a , b ] 内必有一根 x ∗ x^* x ∗ 。通

    2024年02月04日
    浏览(48)
  • 牛顿法、割线法、二分法

    牛顿法求解非线性方程组 割线法求解非线性方程组 二分法求解根号3  另外,今天上机课写程序时,发现不同的起始点可以收敛到不同的零点。也许这是一个新的值得研究的地方。 看来,计算数学也是这样,光听理论无法实现大的突破,也没法产生好的想法,必须在实践应用

    2024年02月05日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包