在一个区间内的最大公约数

在一个区间内的最大公约数

设 x 和 y 为两个数字。在这种情况下,如果当 y 除以 x 时返回零余数,则称 x 是 y 的除数。区间中出现的最大除数是该区间最大元素数的除数。

问题陈述

给定一个区间 [a, b]。找出包含 a 和 b 的范围内(除了“1”之外)出现的最大除数。如果所有除数出现次数相同,则返回 1。

示例 1

Input [2, 5]
Output 2

解释 – 2 的约数 = {1, 2},3 的约数 = {1, 3},4 的约数 = {1, 2, 4},5 的约数 = {1 , 5}。 2 是出现次数最多的除数。

示例 2

Input [2, 5]
Output 2

解释 – 2 的约数 = {1, 2},3 的约数 = {1, 3},4 的约数 = {1, 2, 4},5 的约数 = {1 , 5}。 2 是出现次数最多的除数。

方法 1:暴力破解

解决该问题的强力方法是找到区间内所有数字的所有约数,并将它们连同出现的次数一起存储在映射中。

算法

过程除数(num)

对于 i = 1 到 n1/2+1

如果 num%i == 0

如果 num/i == i

如果 i 不在地图中,则插入 (i, 1)

否则映射[i]++

其他

如果 i 不在地图中,则插入 (i, 1)

否则映射[i]++

如果 num/i 不在地图中,则插入 (num/i, 1)

其他地图[num/i]++

过程 maxDivisors (a, b)

对于 n = a 到 b

除数 (n)

map.erase(1)

除数 = 1,计数 = int_min

对于地图中的每个元素

if it.value > 计数

计数 = it.value

除数 = it.key

示例:C++ 实现

在下面的程序中,我们在 divisors() 函数中查找每个数字的约数,并在 maxdivisor() 函数中查找最大出现的除数。

#include using namespace std;// map storing occurrence of each divisorunordered_map occ;// function to find all the divisors of a number and store it in mapvoid divisors(int num){   for (int i = 1; i <= (sqrt(num) + 1); i++)    {         // checking if i is divisor of num      if (num % i == 0)        {               // checking if num has identical divisors i.e. if i*i == num         // if identical divisors then save only one         if (num / i == i) {            if (occ.find(i) == occ.end()) {               occ.insert(make_pair(i, 1));            }            else{               occ[i]++;            }         }         else{                     // saving divisor i            if (occ.find(i) == occ.end()) {               occ.insert(make_pair(i, 1));            }            else{               occ[i]++;            }                        // saving the divisor of num corresponding to i            if (occ.find(num / i) == occ.end()) {               occ.insert(make_pair(num / i, 1));            }            else{               occ[num / i]++;            }         }      }   }}// function to find maximum occurring divisor in an intervalint maxDivisor(int a, int b){   for (int n = a; n second > cnt) {         cnt = it->second;         div = it->first;      }   }   return div;}int main(){   int a = 4, b = 7;   cout << "For the interval [" << a << ", " << b << "] maximum occurring divisor = ";   cout << maxDivisor(a, b);   return 0;}

输出

For the interval [4, 7] maximum occurring divisor = 2

时间复杂度 – O(n3/2),因为对于区间中的每个数字,为​​了查找除数,执行复杂度为 O(n1/2) 的循环。

空间复杂度 – O(n),地图空间。

方法 2

可以通过减少用每个除数的出现来填充映射的时间来进一步优化上述方法。不是找到每个数字的除数,而是可以通过计算区间的下限和上限来获知区间中每个除数的出现情况。

让我们以区间 [2, 5] 为例。

可能的约数集是从 1 到 5。因此,出现 1 = 5/1 – 2/1 +1 = 4。出现 2 = 5/2 – 2/2 + 1 = 2。出现 3 = 5/3 – 2/3 = 1。出现 4 = 5/4 – 2/4 = 1。出现 5 = 5/5 – 2/5 = 1。

以上可以形式化为,

如果下界%除数 == 0 则 occ = 上界/除数 – 下界/除数 + 1

其他 occ = 上界/除数 – 下界/除数

算法

过程 maxDivisor (a, b)

对于 i = 2 到 b

如果 a%i == 0

次数 = b/i – a/i +1

其他

次数 = b/i – a/i

map.insert(i, 次)

除数 = 1,计数 = int_min

对于地图中的每个元素

if it.value > 计数

计数 = it.value

除数 = it.key

示例:C++ 实现

在下面的程序中,我们不是按相反的顺序查找数字的除数,而是针对每个除数查找它在区间内有多少个倍数。

#include using namespace std;// function to find maximum occurring divisor in an intervalint maxDivisor(int a, int b){   // map used to store occurrences of divisors   unordered_map occ;   for (int i = 2; i second > cnt){         cnt = it->second;         div = it->first;      }   }   return div;}int main(){   int a = 1, b = 10;   cout << "For the interval [" << a << ", " << b << "] maximum occurring divisor = ";   cout << maxDivisor(a, b);   return 0;}

输出

For the interval [1, 10] maximum occurring divisor = 2

方法 3

该问题的一个非常简单的解决方案如下所示,

在任何大小 > 1 的区间中,一半的数字(每个偶数)将以 2 作为除数。

因此可以如下使用。

算法

过程 maxDivisors (a, b)

如果 a == b

ans = a

其他

ans = 2

示例:C++ 实现

在下面的程序中,我们实现了每个偶数都有 2 作为约数的观察结果。

#include using namespace std;// function to find the maximum occurring divisor in an intervalint maxDivisor(int a, int b){   if (a == b){      return a;   } else {      return 2;   }}int main(){   int a = 1, b = 10;   cout << "For the interval [" << a << ", " << b << "] maximum occurring divisor = ";   cout << maxDivisor(a, b);   return 0;}

输出

For the interval [1, 10] maximum occurring divisor = 2

结论

总之,为了找到一个区间内最大出现除数,我们可以使用上述方法,时间范围从 O(n3/2) 到 O(1),空间范围从 O(n) 到 O( 1).

以上就是在一个区间内的最大公约数的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1444188.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月17日 21:09:30
下一篇 2025年12月17日 21:10:09

相关推荐

  • JavaScript数学库开发

    答案:开发JavaScript数学库需明确功能范围,包括基础扩展、统计计算、数值处理等,使用ES模块组织代码,确保测试覆盖边界情况,并发布至npm。 开发一个JavaScript数学库,核心是提供简洁、可靠且易于使用的数学函数。这类库可以用于前端计算、数据处理或科学运算场景。重点在于封装常用但原生J…

    2025年12月20日
    000
  • js中判断日期是否在区间内怎么写

    判断js日期是否在区间内需将日期统一转换为时间戳比较。具体步骤:1.使用gettime()方法将date对象转为毫秒数,再通过比较数字大小判断日期范围;2.若输入是字符串,则先用new date()转换为日期对象;3.为避免时区问题,可统一使用utc时间,利用date.utc()结合getutc方法…

    2025年12月20日 好文分享
    000
  • 求最大公约数

    编写一个接受两个数字并返回它们的最大公约数 (gcd) 的函数。 解决方案 function findgcd(number1, number2) { if(number2 === 0) { return number1; } return findgcd(number2, number1 % num…

    2025年12月19日
    000
  • “为什么我们需要算法:效率、自动化和解决问题的基础”

    _ 算法对于在各个领域,特别是在计算、数学和日常生活中有效地解决问题、做出决策和系统地执行任务至关重要。这就是我们需要算法的原因:_ 1. 效率与优化 算法使我们能够通过减少所需的时间、精力或资源,以最有效的方式解决问题。 示例:在计算机科学中,像 QuickSort 或 MergeSort 这样的…

    2025年12月19日
    000
  • c++ 最大公约数算法 c++ gcd函数实现代码

    最大公约数常用欧几里得算法实现,递归和迭代方式分别为gcd(b, a % b)和循环取余,C++17起可用std::gcd,需注意输入非负。 在C++中实现最大公约数(GCD)最常用的方法是使用欧几里得算法(辗转相除法)。这个方法效率高,代码简洁。C++17起标准库也提供了std::gcd,但手动实…

    2025年12月19日
    000
  • c++如何求两个数的最大公约数_c++求GCD算法实现方法

    最大公约数常用欧几里得算法求解,递归和迭代实现均基于GCD(a, b) = GCD(b, a % b),直至b为0;推荐使用迭代法避免栈溢出,处理负数时取绝对值,多个数的GCD可两两计算。 在C++中求两个数的最大公约数(GCD,Greatest Common Divisor)有多种方法,最常用且高…

    2025年12月19日
    000
  • c++中如何计算两个数的最小公倍数_c++最小公倍数计算方法

    最小公倍数可通过最大公约数计算,公式为LCM(a, b) = a / GCD(a, b) * b,推荐手动实现GCD并使用long long类型防溢出。 在C++中计算两个数的最小公倍数(LCM,Least Common Multiple),通常借助它们的最大公约数(GCD,Greatest Com…

    2025年12月19日
    000
  • c++中//什么意思 单行注释符号使用规范

    c++++中,//表示单行注释,用于让编译器忽略该行中//之后的内容。使用规范包括:1. 简洁明了,2. 放在需要解释的代码附近,3. 暂时禁用代码,4. 保持一致性。 在C++中,//表示单行注释,它的作用是让编译器忽略该行中//之后的内容。这是一个非常常见且方便的注释方式,用于在代码中添加简短的…

    2025年12月18日
    000
  • c语言函数最大公约数最小公倍数是什么

    C语言中,可以使用辗转相除法高效计算最大公约数和最小公倍数。GCD函数采用递归实现,初始处理负数和零,随后不断更新最大公约数,直至余数为零。LCM函数利用GCD函数计算,其为两数乘积除以GCD。为避免整数溢出,使用long long类型。迭代版本的GCD函数避免递归,提高稳定性。常见错误包括未处理负…

    2025年12月18日
    000
  • c语言函数怎么表示最大公约数教程

    C 语言中高效优雅地求最大公约数的方法:使用辗转相除法,通过不断除数取余直到余数为 0 的方式求解。提供了递归和迭代两种实现方式,递归实现简洁明了,迭代实现性能更高,更稳定。注意处理负数和 0 的情况,并考虑性能优化,但辗转相除法本身已足够高效。 C语言里怎么优雅地求最大公约数? 你可能觉得求最大公…

    2025年12月18日
    000
  • c语言函数最大公约数怎么表示教程

    最大公约数在 C 语言中可以通过辗转相除法计算,利用欧几里得算法不断取余,直到余数为 0,最后的除数即为最大公约数。对于递归代码存在的栈溢出风险,可采用迭代实现,利用循环不断进行取余运算,同样可以得到最大公约数。此外,考虑到负数处理,可进一步优化代码,利用 abs() 函数将负数转换为正数,增强代码…

    2025年12月18日
    000
  • c语言函数定义格式有哪些

    C语言函数定义的关键元素包括:返回类型(定义函数返回的值)、函数名(遵循命名规范,决定作用域)、参数列表(定义函数接受的参数类型、数量和顺序)和函数体(实现函数的逻辑)。明确这些元素的意义和微妙关系至关重要,能帮助开发者避免“坑”,编写更高效、更优雅的代码。 C语言函数定义:那些你可能不知道的细节 …

    2025年12月18日
    000
  • C语言算法问答集:算法思维在现实世界中的体现

    求最大公约数:采用欧几里德算法,判断两数是否互质,若否,则以较大数对较小数取模,直至较小数为 0,此时较大数即为最大公约数。求斐波那契数列:可采用递归或迭代算法,递归算法利用斐波那契数列的递推公式,迭代算法则通过循环计算斐波那契数列的每一项。判断素数:基于试除法,从 2 开始依次判断数字是否可被从 …

    2025年12月18日
    000
  • C语言算法问答集:解决常见问题

    问题 1:求最大公约数,代码:int gcd(int a, int b) {…}。问题 2:求数组总和,代码:int sum(int arr, int size) {…}。问题 3:求阶乘,代码:int factorial(int n) {…}。问题 4:反转字符…

    2025年12月18日
    000
  • C语言算法:面试真题与应试技巧

    解答:求解最大公约数(gcd)的 c 语言代码实现了欧几里德算法。应试技巧包括:1. 掌握基础算法(查找、排序、递归、贪心);2. 理解问题;3. 算法设计(选择最优算法);4. 实现代码(清晰、简洁、高效);5. 测试用例设计;6. 时间和空间复杂度分析;7. 自信和清晰的面试表现。遵循这些技巧有…

    2025年12月18日
    000
  • C++ 函数中引用和指针传递示例讲解

    在 c++++ 中,函数参数可以按值、引用或指针传递。按值传递仅复制变量的值,按引用传递直接修改原始变量,而按指针传递则通过内存地址修改原始变量。 C++ 函数中引用和指针传递示例讲解 什么是引用和指针? 引用:引用就像一个变量的别名,指向变量存储的内存地址。指针:指针是一个变量,存储另一个变量的内…

    2025年12月18日
    000
  • C++ 函数返回类型指定技巧与注意事项

    在 c++++ 中,始终指定函数的返回类型至关重要,以优化性能、防止错误和提高可读性。技巧包括:使用合适的类型、避免返回 void、使用合适的返回类型修饰符、考虑默认返回值。实战案例:gcd 函数计算两个整数的最大公约数,并返回无符号整数。 C++ 函数返回类型指定技巧与注意事项 在 C++ 中,始…

    2025年12月18日
    000
  • C++技术中的调试:实现自动化测试驱动的调试

    atdd 是一种强大的调试技术,通过自动化测试用例来识别缺陷并解决问题。在 c++++ 中,可以使用 gtest、catch2 和 boost.test 等测试框架来实现 atdd。这些测试用例验证代码的正确性并确定问题的根源。通过 atdd,开发者可以加快调试流程,提高代码质量,并减少生产中的缺陷…

    2025年12月18日
    000
  • 模板化编程中的常见陷阱和最佳实践?

    模板化编程在c++++中易出现陷阱,如过度通用、虚假依赖和复杂性。最佳实践包括保持简单、使用特殊化、关注代码可读性和使用概念。遵循这些最佳实践可编写灵活、高效且可维护的代码。 模板化编程的陷阱与最佳实践 在C++中,模板化编程是一种强大的技术,可用于创建灵活且可重用的代码。然而,它也容易出现陷阱,导…

    2025年12月18日
    000
  • C++ 函数指针参数的 const 限定符

    C++ 函数指针参数的 const 限定符 函数指针是指向函数的指针,它提供了在运行时动态调用函数的能力。函数指针参数通常用于将回调传递给其他函数。 const 限定符可以应用于函数指针参数,以指定函数指针指向的函数不能被修改。这确保了函数指针指向的函数在调用期间不会被意外覆盖或修改。 语法 voi…

    2025年12月18日
    000

发表回复

登录后才能评论
关注微信