当前位置: 首页 > article >正文

算法通关村-----数论问题解析

最大公约数和最小公倍数

概念描述

最大公约数(GCD)是指两个或多个整数共有约数中的最大值。
最小公倍数(LCM)是指两个或多个整数共有的倍数中的最小值

方法介绍

碾转相除法

一种用于计算两个整数的最大公约数(GCD)的方法。它基于以下原理:两个数的最大公约数等于其中较小数除以它们的余数的最大公约数。
该算法的步骤如下:

  1. 将两个整数记为a和b,其中a是较大的数,b是较小的数。
  2. 用a除以b,得到一个商q和余数r。
  3. 如果r等于0,则b就是最大公约数,算法结束。
  4. 如果r不等于0,则将a更新为b,b更新为r,然后返回第二步继续执行。
  5. 重复执行步骤2-4,直到余数为0为止。

两个数的乘积除以两个数的最大公约数即为两个数的最小公倍数

代码实现

求解最大公约数

public int gcd(int a, int b) {
    int k = 0;
    while (k!=0){
        k = a%b;
        a = b;
        b = k;
    };
    return a;
}

求解最小公倍数

public int mcl(int a, int b) {
    int gcd = gcd(a, b);
    return a * b / gcd;
}

素数与合数

概念介绍

素数又称为质数,素数首先要满足大于等于2,并且除了1和它本身之外,不能被任何其他自然数整除。其他数都是合数。比较特殊的是1即非素素数,也非合数。2是唯一的同时为偶数和素数的数字。

方法介绍

要判断一个数是否为质数,可以使用以下方法:

  1. 特殊情况处理:首先排除小于2的数,因为质数定义为大于1的自然数。
  2. 试除法:从2开始,逐个将待判断的数除以从2到其平方根范围内的所有整数(包括平方根),如果能够整除,则该数不是质数。如果在整个范围内都没有找到能整除的数,则该数是质数。

代码实现

public boolean isPrime(int num){
    int max = (int)Math.sqrt(num);
    for (int i = 2; i<=max;i++){
        if(num%i==0){
            return false;
        }
    }
    return true;
}

质数计数

问题描述

给定整数 n ,返回所有小于非负整数 n 的质数的数量 。详见leetcode204

问题分析

最直接的方式就是从2开始遍历,每次利用上面的质数判断代码对每一个数字进行判断,如果是质数,计数器➕1,直至计数器为n,返回当前质数。这样做时间复杂度过高。可以通过空间换时间的方式来操作,设置一个长度为n的数组,初始时,设置数组全为1,之后,从下标2开始遍历,如果数组当前值为1,质数计数器➕1,并将当前数字的倍数以及与倍数相关的非质数下标设置为0,最后返回质数计数器的值。这种方式也被称为埃氏筛

代码实现

直接方式

public int countPrimes(int n) {
    int count = 0;
    for(int i=2;i<n;i++){
        if(isPrime(i)){
            count++;
        }
    }
    return count;
}

public boolean isPrime(int num){
    int max = (int)Math.sqrt(num);
    for (int i = 2; i<=max;i++){
        if(num%i==0){
            return false;
        }
    }
    return true;
}

埃氏筛方式

public int countPrimes(int n) {
    int[] isPrime = new int[n];
    int count = 0;
    Arrays.fill(isPrime,1);
    for(int i=2;i<n;i++){
        if(isPrime[i]==1){
            count++;
            if((long)i*i<n){
                for(int j=i*i;j<n;j+=i){
                    isPrime[j]=0;
                }
            }
        }
    }
    return count;
}

丑数判断

问题描述

丑数 就是只包含质因数 2、3 和 5 的正整数。

给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。详见leetcode263

问题分析

可以直接根据丑数的概念进行判断。如果不包含质因数或者包含质因数 2、3 和 5 的正整数即为丑数

代码实现

public boolean isUgly(int n) {
    if(n<=0){
    	return false;
    }
    int[] factors = new int[]{2,3,5};
    for(int factor:factors){
        while(n%factor==0){
            n = n/factor;
        }
    }
    return n==1;
}

丑数计数

问题描述

给你一个整数 n ,请你找出并返回第 n 个 丑数 。详见leetcode264

问题分析

最直接的方式就是从1开始遍历,每次利用上面的丑数判断代码对每一个数字进行判断,如果是质数,计数器➕1,直至计数器为n,返回当前丑数。这样做时间复杂度过高。可以通过空间换时间的方式来操作,设置一个小顶堆,初始时,将最小的丑数1加入队中,循环n次,每次将堆顶元素x移除,每次将2x,3x,5x放入堆中,为了避免重复,可以使用集合过滤,循环n次之后,最小的第n个丑数出堆返回

代码实现

直接方式

public int nthUglyNumber(int n) {
    int count = 0;
    int i=1;
    while(true){
        if(isUgly(i)){
            count++;
            if(count==n){
                return i;
            }
        }
        i++;
    }
}

public boolean isUgly(int num){
    if(num<=0){
        return false;
    }
    int[] factors = new int[]{2,3,5};
    for(int factor:factors){
        while(num%factor==0){
            num = num/factor;
        }
    }
    return num==1;
}

最小堆方式

public int nthUglyNumber(int n) {
    int[] factors = {2, 3, 5};
    Set<Long> seen = new HashSet<Long>();
    PriorityQueue<Long> heap = new PriorityQueue<Long>();
    seen.add(1L);
    heap.offer(1L);
    int ugly = 0;
    for (int i = 0; i < n; i++) {
        long curr = heap.poll();
        ugly = (int) curr;
        for (int factor : factors) {
            long next = curr * factor;
            if (seen.add(next)) {
                heap.offer(next);
            }
        }
    }
    return ugly;
}

http://www.kler.cn/news/149707.html

相关文章:

  • P9240 [蓝桥杯 2023 省 B] 冶炼金属(比值问题)
  • 国内划片机行业四大企业之博捷芯:技术驱动,领跑未来
  • 智能优化算法应用:基于回溯搜索算法无线传感器网络(WSN)覆盖优化 - 附代码
  • 每日一练:约瑟夫生者死者小游戏
  • Spring Application Event 在事件驱动设计中的应用
  • 西南科技大学数字电子技术实验二(SSI逻辑器件设计组合逻辑电路及FPGA实现 )预习报告
  • python tkinter 使用(七)
  • 3-Python与设计模式--简单工厂模式
  • Android平台GB28181设备接入模块开发填坑指南
  • C++-多态常见试题的总结
  • 物联网边缘计算是什么?如何实现物联网边缘计算?
  • NX二次开发UF_CURVE_create_combine_curves 函数介绍
  • 工业智能网关如何保障数据通信安全
  • 【华为数通HCIP | 网络工程师】821刷题日记-BFD和VRRP 及重点(1)
  • shopee买家通系统批量注册虾皮买家号的软件
  • Linux基本指令总结(二)
  • 【设计模式】行为型模式-第 3 章第 5 讲【观察者模式】
  • CSS特效020:涌动的弹簧效果
  • thinkphp6生成PDF自动换行
  • Iar 8051等各种版本安装破解过程
  • 基于UI交互意图理解的异常检测方法
  • 基于FPGA的五子棋游戏设计
  • 在线 SQL 模拟器SQL Fiddle使用简介
  • Python3基础
  • 爬虫-基于python的旅游景点推荐系统的设计与实现-计算机毕业设计源码24044
  • Linux加强篇002-部署Linux系统
  • SimpleDateFormat在多线程下的安全问题
  • 392. 判断子序列
  • 【JavaScript】3.3 JavaScript工具和库
  • 【开题报告】基于深度学习的驾驶员危险行为检测系统