数学
素数
素数分解
每一个数都可以分解成素数的乘积,例如 84 = 22 * 31 * 50 * 71 * 110 * 130 * 170 * …
整除
令 x = 2m0 * 3m1 * 5m2 * 7m3 * 11m4 * …
令 y = 2n0 * 3n1 * 5n2 * 7n3 * 11n4 * …
如果 x 整除 y(y mod x == 0),则对于所有 i,mi <= ni。
生成素数序列
埃拉托斯特尼筛法在每次找到一个素数时,将能被素数整除的数排除掉。
class Solution {
public int countPrimes(int n) {
boolean[] notPrimes = new boolean[n + 1];
int count = 0;
for (int i = 2; i < n; i++) {
if (notPrimes[i]) {
continue;
}
count++;
for (long j = (long) i * i; j < n; j += i) {
notPrimes[(int) j] = true;
}
}
return count;
}
}
最大公约数
最大公约数最小公倍数
x 和 y 的最大公约数为:gcd(x,y) = 2min(m0,n0) * 3min(m1,n1) * 5min(m2,n2) * …
x 和 y 的最小公倍数为:lcm(x,y) = 2max(m0,n0) * 3max(m1,n1) * 5max(m2,n2) * …
使用位操作和减法求解最大公约数
对于 a 和 b 的最大公约数 f(a, b),有:
- 如果 a 和 b 均为偶数,f(a, b) = 2*f(a/2, b/2);
- 如果 a 是偶数 b 是奇数,f(a, b) = f(a/2, b);
- 如果 b 是偶数 a 是奇数,f(a, b) = f(a, b/2);
- 如果 a 和 b 均为奇数,f(a, b) = f(b, a-b);
乘 2 和除 2 都可以转换为移位操作。
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
最小公倍数为两数的乘积除以最大公约数。
int lcm(int a, int b) {
return a * b / gcd(a, b);
}
进制转换
7 进制
class Solution {
public String convertToBase7(int num) {
if (0 == num) {
return "0";
}
boolean negative = num < 0 ? true : false;
if (negative) {
num = - num;
}
StringBuilder result = new StringBuilder();
int a = 0, b = 0;
while (num > 0) {
a = num / 7;
b = num % 7;
num = a;
result.append(b);
}
String ret = result.reverse().toString();
return negative == true ? "-" + ret : ret;
}
}
Java 中 static String toString(int num, int radix) 可以将一个整数转换为 radix 进制表示的字符串。
public String convertToBase7(int num) {
return Integer.toString(num, 7);
}
16 进制
405. Convert a Number to Hexadecimal (Easy)
Input:
26
Output:
"1a"
Input:
-1
Output:
"ffffffff"
负数要用它的补码形式。
class Solution {
public String toHex(int num) {
if (0 == num) {
return "0";
}
char[] map = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a'