算法通关村第十三关|黄金挑战|数论问题

1.辗转相除法(欧几里得算法)

假如 8 和 12 的最大公因数是 4 ,就记作 gcd(8,12)=4.

辗转相除法重要规则:若 r 是 a÷b 的余数,则 gcd(a,b)=gcd(b,r) 。

基于该规则的代码实现:

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

2.素数和合数

验证是否为素数:从 2 到 n^(1/2) 遍历,如果取余得 0 就不是素数。

扩展题:力扣204 计数质数

public int countPrimes(int n) {
	int cnt = 0;
	for (int i = 2; i < n; i++) {
        if (isPrime(i)) {
            cnt++;
        }
    }
	return cnt;
}
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 的时候性能不够。在力扣上提交会超时。

3.埃氏筛

可以用埃氏筛解决上面题目的性能问题。

基本思想:如果 x 是质数,那么 x 的倍数一定不是质数。

解题思路:选中 2 ,将 2 的倍数全部排除,然后选中 3 ,将 3 的倍数全部排除,以此类推。当然,被排除的数就不用再被选中了。

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

这种解法节省了大量执行时间,但是也占用了相当的空间。

4.丑数问题

4.1 判断是否为丑数

只包含质因子 2 , 3 , 5 的数称作丑数。

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;
}

4.2 求第n个丑数

剑指offer的题目:把只包含质因子 2 , 3 , 5 的数称作丑数,求按从小到大的顺序的第 n 个丑数。

如果对您有帮助,请点赞关注支持我,谢谢!❤
如有错误或者不足之处,敬请指正!❤
个人主页:星不易 ❤
算法通关村专栏:不易|算法通关村 ❤

你可能感兴趣的:(不易,算法通关村,算法,java,算法通关村)