本专栏开启,目的在于帮助大家更好的掌握学习Java
,特别是一些Java学习者
难以在网上找到系统地算法学习资料帮助自身入门算法,同时对于专栏内的内容有任何疑问都可在文章末尾添加我的微信给你进行一对一的讲解。
但最最主要的还是需要独立思考,对于本专栏的所有内容,能够进行完全掌握,自己完完全全将代码写过一遍,对于算法入门肯定是没有问题的。
算法的学习肯定不能缺少总结,这里我推荐大家可以到高校算法社区将学过的知识进行打卡,以此来进行巩固以及复习。
学好算法的唯一途径那一定是题海战略,大量练习的堆积才能练就一身本领。专栏的任何题目我将会从【题目描述】【解题思路】【模板代码】【代码解析】等四板块进行讲解。
算术基本定理是一个非要重要的定理,它的存在是许多重要公式的基础,比如前两天我们学习的约数个数和约数之和算法。它都是建立在算术基本定理上,当时我们直接进行了质因数分解的,可能有的小伙伴还不太理解。今天我们系统来进行讲解一下
算术基本定理课表述为:任何一个大于 1 1 1的自然数
N N N,如果 N N N不为质数
,那么 N N N可以唯一分解成有限个数的乘积:
N = ∏ i = 1 k p i i = p 1 a 1 × p 2 a 2 × p 3 a 3 . . . . . . p k a k ( p 1 , p 2 . . . . p k 均 为 质 数 ) N=\prod_{i=1}^{k} p_i^{^i}=p_1^{a^1}\times p_2^{a^2}\times p_3^{a^3}......p_k^{a^k}(p_1,p_2....p_k均为质数) N=i=1∏kpii=p1a1×p2a2×p3a3......pkak(p1,p2....pk均为质数)
其中指数 a i a_i ai均为正整数,这样的分解式称为 N N N的标准分解式。最早是由欧几里得证明给出。 算术基本定理的证明在此我们不细讲,拓展一些基于算术基本定理可以得到的一些证明。
给定 n ( 1 ≤ n ≤ 100 ) n(1 \le n \le 100) n(1≤n≤100)个正整数 a i ( 2 ≤ a i ≤ 2 ∗ 1 0 9 ) a_i(2 \le a_i \le2*10^9) ai(2≤ai≤2∗109),将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。
long
读取。import java.util.*;
public class a {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
for (int i = 0; i < n; i++) {
long x=sc.nextLong();
test(x);
}
}
static void test(long x){
for (int i = 2; i <=x;i++) {
if (x%i==0){
int ans=0;
while (x%i==0){
x/=i;
ans++;
}
System.out.println(i+" "+ans);
}
}
}
}
但很明显我们发现,设每个数的取值范围为 m m m,时间复杂达到了 O ( n m ) O(nm) O(nm),这是不可接收的,我们考虑对test
函数进行优化
static void test(long x){
for (int i = 2; i <=x/i;i++) {
if (x%i==0){
int ans=0;
while (x%i==0){
x/=i;
ans++;
}
System.out.println(i+" "+ans);
}
}
if (x>1) System.out.println(x+" "+1);
}
test
操作我们优化为 O ( n ) O(\sqrt n) O(n)。它基于的原理是对于一个正整数 n n n,它的质因数中大于 n \sqrt n n的最多只能有一个。这也很好证明,假设有两个,那么相乘肯定大于 n n n了。序号 | 题目链接 | 难度评级 |
---|---|---|
1 | 丑数3 | 2 |