【二分查找】自写二分函数的总结

2023-12-17 23:01

本文主要是介绍【二分查找】自写二分函数的总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者推荐

【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数

本文涉及的基础知识点

二分查找算法合集

自写二分函数 的封装

我暂时只发现两种:
一,在左闭右开的区间寻找最后一个符合条件的元素,我封装成FindEnd函数。
二,在左开右闭的区间寻找第一个符合条件的元素,我封装成FindFirst函数。

namespace NBinarySearch
{template<class INDEX_TYPE,class _Pr>INDEX_TYPE FindFrist(INDEX_TYPE left, INDEX_TYPE rightInclue, _Pr pr){while (rightInclue - left > 1){const auto mid = left + (rightInclue - left) / 2;if (pr(mid)){rightInclue = mid;}else{left = mid;}}return rightInclue;}template<class INDEX_TYPE, class _Pr>INDEX_TYPE FindEnd(INDEX_TYPE leftInclude, INDEX_TYPE right, _Pr pr){while (right - leftInclude > 1){const auto mid = leftInclude + (right - leftInclude) / 2;if (pr(mid)){leftInclude = mid;}else{right = mid;}}return leftInclude;}
}

左闭右开 左开右闭的例子

LeetCode33: C++算法:二分查找旋转数组

class Solution {
public:int search(vector<int>& nums, int target) {int rBegin = NBinarySearch::FindFrist(-1, (int)nums.size() - 1, [&](const int mid) {return nums[mid] <= nums.back(); });if (target <= nums.back()){return Find(nums, rBegin, nums.size(), target);}return Find(nums, 0, rBegin, target);}int Find(const vector<int>& nums, int left, int r, int target){int iRet = NBinarySearch::FindEnd(left,r, [&](const int mid) {return nums[mid] <= target; });return (target == nums[iRet]) ? iRet : -1;}
};
int main()
{vector<int> vNums = { 1,2,3,4,6 };auto res = Solution().search(vNums, 4);std::cout << "index:" << res;if (-1 != res){std::cout << " value:" << vNums[res];}
}

左闭右开的例子

Leetcode2790:C++二分查找算法的应用:长度递增组的最大数目

namespace NBinarySearch
{template<class INDEX_TYPE,class _Pr>INDEX_TYPE FindFrist(INDEX_TYPE left, INDEX_TYPE rightInclue, _Pr pr){while (rightInclue - left > 1){const auto mid = left + (rightInclue - left) / 2;if (pr(mid)){rightInclue = mid;}else{left = mid;}}return rightInclue;}template<class INDEX_TYPE, class _Pr>INDEX_TYPE FindEnd(INDEX_TYPE leftInclude, INDEX_TYPE right, _Pr pr){while (right - leftInclude > 1){const auto mid = leftInclude + (right - leftInclude) / 2;if (pr(mid)){leftInclude = mid;}else{right = mid;}}return leftInclude;}
}class Solution {
public:int maxIncreasingGroups(vector<int>& usageLimits) {m_c = usageLimits.size();m_v = usageLimits;sort(m_v.begin(), m_v.end());auto Can = [&](int len){int i = m_c - 1;long long llNeed = 0;for (; len > 0; len--, i--){llNeed -= (m_v[i] - len);if (m_v[i] >= len){llNeed = max(0LL, llNeed);}}for (; i >= 0; i--){llNeed -= m_v[i];}return llNeed <= 0;};return NBinarySearch::FindEnd(1, m_c + 1, Can);}int m_c;vector<int> m_v;
};
template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{Solution slu;vector<int> usageLimits;int res = 0;usageLimits = { 2,2,2 };res = slu.maxIncreasingGroups(usageLimits);Assert(res, 3);usageLimits = { 1,2,5 };res = slu.maxIncreasingGroups(usageLimits);Assert(res, 3);usageLimits = { 2,1,2 };res = slu.maxIncreasingGroups(usageLimits);Assert(res, 2);usageLimits = { 1,1 };res = slu.maxIncreasingGroups(usageLimits);Assert(res, 1);//CConsole::Out(res);
}

左闭右开的应用

C++二分查找算法的应用:最小好进制

Is

计算是否存在m位 k进制的1为目标数。m位iRet 进制1大于等于目标数,可能有多个符合的iRet,取最小值。非最小值一定不是。

namespace NBinarySearch
{template<class INDEX_TYPE,class _Pr>INDEX_TYPE FindFrist(INDEX_TYPE left, INDEX_TYPE rightInclue, _Pr pr){while (rightInclue - left > 1){const auto mid = left + (rightInclue - left) / 2;if (pr(mid)){rightInclue = mid;}else{left = mid;}}return rightInclue;}template<class INDEX_TYPE, class _Pr>INDEX_TYPE FindEnd(INDEX_TYPE leftInclude, INDEX_TYPE right, _Pr pr){while (right - leftInclude > 1){const auto mid = leftInclude + (right - leftInclude) / 2;if (pr(mid)){leftInclude = mid;}else{right = mid;}}return leftInclude;}
}class Solution {
public:string smallestGoodBase(string n) {long long llN = 0;for (const auto& ch : n){llN = (llN * 10 + ch - '0');}for (int i = 70; i > 2; i--){long long llRet = Is(i, llN);if (llRet > 0){return std::to_string(llRet);}}return std::to_string(llN - 1);}long long Is(int m, long long n){int iRet = NBinarySearch::FindEnd(2LL, n + 1LL, [&](const auto mid) {return Cmp(mid, m, n) >= 0; });return (0 == Cmp(iRet,m,n))? iRet : 0;}//k进制的m个1和n的大小比较,n大返回正数,相等返回0,n小返回负数long long Cmp(long long k, int m, long long n){long long llHas = 1;for (; m > 0; m--){if (n < llHas){return -1;}n -= llHas;if (m > 1){// 最后一次llHas并不使用,所以越界不影响if (LLONG_MAX / k < llHas){return -1;}llHas *= k;}}return n;}
};template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{Solution slu;string res;res = slu.smallestGoodBase("470988884881403701");Assert(res, std::string("686286299"));res = slu.smallestGoodBase("2251799813685247");Assert(res, std::string("2"));res = slu.smallestGoodBase("13");Assert(res, std::string("3"));res = slu.smallestGoodBase("4681");Assert(res, std::string("8"));res = slu.smallestGoodBase("1000000000000000000");Assert(res, std::string("999999999999999999"));res = slu.smallestGoodBase("1333");Assert(res, std::string("36"));res = slu.smallestGoodBase("463381");Assert(res, std::string("463380"));//CConsole::Out(res);
}

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

这篇关于【二分查找】自写二分函数的总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/506178

相关文章

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

python中的高阶函数示例详解

《python中的高阶函数示例详解》在Python中,高阶函数是指接受函数作为参数或返回函数作为结果的函数,下面:本文主要介绍python中高阶函数的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录1.定义2.map函数3.filter函数4.reduce函数5.sorted函数6.自定义高阶函数

Python中的sort方法、sorted函数与lambda表达式及用法详解

《Python中的sort方法、sorted函数与lambda表达式及用法详解》文章对比了Python中list.sort()与sorted()函数的区别,指出sort()原地排序返回None,sor... 目录1. sort()方法1.1 sort()方法1.2 基本语法和参数A. reverse参数B.

linux查找java项目日志查找报错信息方式

《linux查找java项目日志查找报错信息方式》日志查找定位步骤:进入项目,用tail-f实时跟踪日志,tail-n1000查看末尾1000行,grep搜索关键词或时间,vim内精准查找并高亮定位,... 目录日志查找定位在当前文件里找到报错消息总结日志查找定位1.cd 进入项目2.正常日志 和错误日

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返

Python Excel 通用筛选函数的实现

《PythonExcel通用筛选函数的实现》本文主要介绍了PythonExcel通用筛选函数的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录案例目的示例数据假定数据来源是字典优化:通用CSV数据处理函数使用说明使用示例注意事项案例目的第一

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法