数学题目系列(一)|丑数|各位和|埃氏筛|欧拉筛

一.丑数

链接:丑数
在这里插入图片描述
分析:

  • 丑数只有2,3,5这三个质因数,num = 2a + 3b + 5c
  • 也就是一个丑数是由若干个2,3,5组成,那么丑数除以这若干个数字最后一定变为1

代码

class Solution {
    public boolean isUgly(int n) {
        if (n <= 0) return false;

        int[] factors = { 2, 3, 5 };
        for (int factor : factors)
            while (n % factor == 0)
                n /= factor;

        return n == 1;
    }
}

二.丑数II

链接:丑数II
在这里插入图片描述
分析

  • 最容易想到的思路是暴力解法,因为在上一题中已经知道判断一个丑数的方法,但是时间复杂度太高,不能通过所有样例

暴力解法(无法通过所有样例)

class Solution {
    private boolean isUgly(int n) {
        int[] factors = {2,3,5};
        for(int factor : factors)
            while(n % factor == 0)
                n /= factor;

        return n == 1;
    }
    public int nthUglyNumber(int n) {
        int ret = 0, cnt = 0;
        for(int i = 1;;i++) {
            if(isUgly(i)) cnt++;
            if(cnt == n) return i;
        }
    }
}
  • 要取出第n大的丑数,可以使用优先级队列来存储丑数,丑数非常容易获得,就是由前一个丑数分别乘2,3,5所得
  • 首先创建最小堆,堆顶元素为最小的丑数
  • 初始化最小堆,堆顶元素为最小的丑数1
  • 取出堆顶元素x,第几次取出就是第几大的丑数
  • x是丑数,那么2x,3x,5x也都是丑数,将这三个数存储到优先级队列之中
  • 在这个过程中可能会出现重复元素,可以使用哈希表来去重
  • 这样,当第n次取出堆顶元素x时,x就是第n大的丑数

代码

class Solution {
    public int nthUglyNumber(int n) {
        int[] factors = {2, 3, 5};
        Set<Long> set = new HashSet<>();
        PriorityQueue<Long> q = new PriorityQueue<>();

        set.add(1L);
        q.add(1L);

        for(int i = 1; i < n; i++) {
            long top = q.poll();
            for(int factor : factors){
                long next = top * factor;
                if(set.add(next))
                    q.add(next); 
            }
        }

        return (int)q.poll().longValue();
    }
}

注意:

  1. 注意Long和long是不同的,Long是包装类,long是基本类型
  2. Java中,基本类型之间可以直接进行强制类型转换(int x = (int)long)
  3. 基本类型和其对应的包装类型在底层是通过方法进行转换的,但是在JDK5之后,编译器会自动帮助我们完成这个过程,也就是拆箱和装箱
  4. 包装类不能直接转换为另一个包装类或原始数据类型,必须先进行拆箱或装箱
  5. Long 不能直接转换为 int,因为它们是不同的类型,必须先将 Long 拆箱为 long,然后再转换为 int。
  6. Long转化为long是通过longvalue方法实现

三.各位相加

链接:各位相加
在这里插入图片描述
分析

  • 模拟思路:不断获得每一位,然后计算各位和,直到最后的结果是个位数

代码

class Solution {
    // 求各位和
    private int bitSum(int n) {
        int ret = 0;
        while (n > 0) {
            ret += n % 10;
            n /= 10;
        }

        return ret;
    }

    public int addDigits(int num) {
        int ret = num;
        while(ret / 10 != 0) {
            ret = bitSum(ret);
        }

        return ret;
    }
}

数学方法
看推导:
在这里插入图片描述

  • 核心在于:num和其各位和 MOD9同余
  • 进而推导出num和最后的结果MOD9同余

代码

class Solution {
    public int addDigits(int num) {
        if(num == 0) return 0;
        if(num % 9 == 0) return 9;
        return num % 9;
    }
}

四.计数质数

暴力解法(超时)

class Solution {
    private boolean isPrime(int n) {
        for(int i = 2; i <= Math.sqrt(n); i++){
            if(n % i == 0)
                return false;
        }

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

埃氏筛

  • 核心:如果x是质数,则2x,3x,4x,5x…一定不是质数
  • 利用这个原理就能灵活处理很多问题

代码

class Solution {
    public int countPrimes(int n) {
        int[] is_prime = new int[n];// 标记第i个数是否是质数
        Arrays.fill(is_prime,1);// 默认全是质数

        int ret = 0;// 记录结果
        for(int i = 2; i < n; i++) {
            if(is_prime[i] == 1) {
                ret += 1;
                if((long)i*i < n)
                    for(int k = i * i; k < n; k += i)
                        is_prime[k] = 0;
            }
        }

        return ret;
    }
}

线性筛

  • 埃氏筛其实还存在冗余的地方,比如12这个数字,被2,4,6都删除过一次,这就是冗余操作,使用线性筛可以解决这个问题
  • 线性筛的核心在于:对于一个数x,x乘以小于x的所有质数的结果一定是合数,将这些结果标记为非质数即可,但是发现这样的删除过程仍然存在冗余操作,问题及解决方案如下

在这里插入图片描述
代码:

class Solution {
    public int countPrimes(int n) {
        List<Integer> list = new ArrayList<>();// 存储之前出现的所有质数
        int[] is_prime = new int[n];
        Arrays.fill(is_prime,1);

        int ret = 0;
        for(int i = 2; i < n; i++) {
            if(is_prime[i] == 1){
                list.add(i);
                ret++;
            }

            for(int k : list){
                if(k*i >= n) break;
                is_prime[k*i] = 0;
                if(i % k == 0) break;// k是i的最小质因数
            }
        }

        return ret;
    }
}

三种算法的时间复杂度对比(数据量大)

  • 线性筛 > 埃氏筛 > 暴力解法

对比实验:求2-n之间所有的质数
代码:

package org.example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// 打印2-n之间的所有质数
public class Demo2 {
    // 埃氏筛
    public static void Eratosthenes(int n) {
        List<Integer> list = new ArrayList<>();
        int[] is_prime = new int[n + 1];
        Arrays.fill(is_prime, 1);

        for(int i = 2; i <= n; i++) {
            if(is_prime[i] == 1){
                list.add(i);
                if((long)i*i <= n)
                    for(int k = i*i; k <= n; k += i)
                        is_prime[k] = 0;
            }
        }
    }

    // 暴力解法
    public static void isPrime(int n){
        List<Integer> list = new ArrayList<>();
        for(int i = 2; i<= n; i++){
            if(is_prime(i))
                list.add(i);
        }
    }

    private static boolean is_prime(int n){
        for(int i = 2; i <= Math.sqrt(n); i++)
            if(n % i == 0)
                return false;
        return true;
    }

    // 线性筛
    public static void Euler_prime(int n){
        List<Integer> list = new ArrayList<>();
        int[] is_prime = new int[n + 1];
        Arrays.fill(is_prime, 1);

        for(int i = 2; i <= n; i++) {
            if(is_prime[i] == 1)
                list.add(i);
            for(int k : list){
                if(k*i > n) break;
                is_prime[k*i] = 0;
                if(i % k == 0) break;// k是i的最小质因数
            }
        }
    }


    public static void main(String[] args) {
        int n = 200000000;
        long start1 = System.currentTimeMillis();
        Eratosthenes(n);
        long end1 = System.currentTimeMillis();
        System.out.println("埃氏筛时间:" + (end1 - start1));

        long start2 = System.currentTimeMillis();
        isPrime(n);
        long end2 = System.currentTimeMillis();
        System.out.println("暴力时间:" + (end2 - start2));

        long start3 = System.currentTimeMillis();
        Euler_prime(n);
        long end3 = System.currentTimeMillis();
        System.out.println("线性筛时间:" + (end3 - start3));
    }
}

打印结果:
在这里插入图片描述

  • 只有当数据量特别大时,才符合上述时间复杂度的排序,对于计算机来说,取模%是一个非常耗时的操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/685755.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker安装、使用,容器化部署springboot项目

一、使用官方安装脚本自动安装 安装命令如下&#xff1a; curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 也可以使用国内 daocloud 一键安装命令&#xff1a; curl -sSL https://get.daocloud.io/docker | sh 二、Docker离线安装 1. 下载安装包 可…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-24.5,6 SPI驱动实验-ICM20608 ADC采样值

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

[数据集][图像分类]城市异常情况路边倒树火灾水灾交通事故分类数据集15223张8类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;15223 分类类别数&#xff1a;8 类别名称:[“badroad”,“fallentree”,“f…

【介绍下Spark MLlib机器学习】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

最优化练习题

def f(x):return x*x-4*x5 a0,b01,31、均匀搜索 令 δ ( b 0 − a 0 ) / N , a i a 0 i δ , i 1 , 2 , 3 \delta(b_0-a_0)/N,a_ia_0i\delta,i1,2,3 δ(b0​−a0​)/N,ai​a0​iδ,i1,2,3 while b0-a0>0.1:anp.linspace(a0,b0,5)for i in range(1,4):if f(a[i-1])>f…

RT-Thread

RT-Thread RT-Thread 版权属于上海睿赛德电子科技有限公司&#xff0c;于 2006年 1月首次发布&#xff0c;初始版 本号为0.1.0&#xff0c;经过 10来年的发展&#xff0c;如今主版本号已经升级到3.0&#xff0c;累计开发者达到数百万&#xff0c; 在各行各业产品中装机量达到了…

zabbix“专家坐诊”第241期问答

问题一 Q&#xff1a;华为交换机的100GE 1/0/1口的光模块收光值监测不到&#xff0c;有没有人碰到过这个问题呢&#xff1f;其他的端口都能监测到收光值&#xff0c;但是100GE 1/0/1口监测不到收光值。底层能查到&#xff0c;zabbix 6.0监控不到&#xff0c;以下是端口的报错信…

引用(C++)和内联函数

前言&#xff1a;本文主要讲解C语法中引用如何使用和使用时的一些技巧 基本语法 引用就是取别名 #include <iostream> using namespace std; int main() {int a 10;int& b a;//给a取别名为bcout << a << endl;cout << b << endl;return 0…

Apple开发者macOS描述文件创建

1.选择Profiles然后点击加号创建 2.选择类型为macOS App Development然后点击继续 3.选择描述类型与App ID 然后点击继续 4.选择证书然后点击继续 5.选择设备,然后点击继续 6.输入描述文件后,点击生成 生成成功,点击下载描述文件 下载完成会自动打开描述文件

1.Rust安装

目录 一、安装1.1 在Windows上安装1.2 在Linux下安装 二、包管理工具三、Hello World3.1 安装IDE3.2 输出Hello World 一、安装 1.1 在Windows上安装 点击页面 安装 Rust - Rust 程序设计语言 (rust-lang.org)&#xff0c;选择"下载RUSTUP-INIT.EXE(64位&#xff09;&qu…

一.网络基础——OSI七层模型

一.OSI七层模型 OSI&#xff08;Open System Interconnection&#xff0c;开放系统互连&#xff09;七层网络模型被称为开放式系统互联参考模型&#xff0c;它是一个逻辑上的定义和规范; 它把网络从逻辑上分为了7层. 每一层都有相关、相对应的物理设备&#xff0c;比如路由器&…

SpringBoot高手之路04-Aop

文章目录 AOP 基础AOP概述start依赖,开发某一个功能,只需要下载这一个依赖,关于他的依赖都会下载下来 AOP快速入门AOP核心概念 切入点表达式-execution AOP 基础 AOP概述 AOP 对特定的方法做增强 AOP 快速入门 start依赖,开发某一个功能,只需要下载这一个依赖,关于他的依赖…

python数据文件处理库-pandas

内容目录 一、pandas介绍二、数据加载和写出三、数据清洗四、数据转换五、数据查询和筛选六、数据统计七、数据可视化 pandas 是一个 Python提供的快速、灵活的数据结构处理包&#xff0c;让“关系型”或“标记型”数据的交互既简单又直观。 官网地址: https://pandas.pydata.o…

Polar Web 【简单】- 被黑掉的站

Polar Web 【简单】- 被黑掉的站 Contents Polar Web 【简单】- 被黑掉的站思路EXP运行&总结 思路 如题目所述&#xff0c;这是一个被黑掉的站点&#xff0c;由此不禁要了解该黑客发现了哪些可以入手的路径&#xff0c;或是留下了什么样的文件供持续访问。 目录扫描该站点发…

AI和机器人引领新一轮农业革命

AI和机器人技术在农业领域的应用正在迅速发展&#xff0c;未来它们可能会实现厘米级精度的自主耕作。 精确种植&#xff1a;AI算法可以分析土壤条件、气候数据和作物生长周期&#xff0c;以决定最佳种植地点和时间。 土壤管理&#xff1a;利用传感器和机器学习&#xff0c;机器…

Windows安装运行elasticsearch服务

官方下载地址&#xff1a;Download Elasticsearch | Elastic 我在linux上执行的下载命令&#xff1a;wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.5.3-linux-x86_64.tar.gz Elasticsearch&#xff08;简称ES&#xff09;是一款基于Apache Lu…

JVM学习-Arthas

Arthas Alibaba开源的Java诊断工具&#xff0c;在线排查问题&#xff0c;无需重启&#xff0c;动态跟踪Java代码&#xff0c;实时监控JVM状态Arthas支持JDK6&#xff0c;支持Linux/Mac/Windows&#xff0c;采用命令行交互模式&#xff0c;同时提供丰富的Tab自动补全功能&#…

前端传参数后端变量类型能够接受到List却无法接收到值

问题描述 今天写了个接口&#xff0c;下图所示 ReqVO里是这样的&#xff1a; 然后前端去请求&#xff0c;从请求结果中看发现这里值是在的&#xff08;有经验的可能就看出来了otherInfo.id: 这样以参数后端是接收不到的&#xff0c;但是当时没发现&#xff09; 传进来后端…

【cmake】cmake cache

cmake cache是什么 cmake cache是cmake在配置好后生成的一个CMakeCache.txt的文件&#xff0c;里面存储了一堆变量&#xff0c;这些变量一般都是关于项目的配置和环境的。 比如你用的什么编译器&#xff0c;编译器选项&#xff0c;还有项目目录。 例如&#xff08;在cmakelist…

uniAPP @input时报错

<input :maxlength"8" v-model"item.value" placeholder"请输入金额" input"inputFn" /> 这些些时会报以下错误 定位了好久之后发现input不支持 v-model和input一起使用 改成以下这般就正常啦 <input :maxlength"8&q…