算法通关村第十三关——数字与数学高频问题(白银)
1. 数组实现加法专题
1.1 数组实现整数加法
根据题意加一,没错就是加一这很重要,因为它是只加一的所以有可能的情况就只有两种:
- 除 999 之外的数字加一;
- 数字 999。
加一得十进一位个位数为 000 加法运算如不出现进位就运算结束了且进位只会是一。
所以只需要判断有没有进位并模拟出它的进位方式,如十位数加 111 个位数置为 000,如此循环直到判断没有再进位就退出循环返回结果。
然后还有一些特殊情况就是当出现 999999、999999999 之类的数字时,循环到最后也需要进位,出现这种情况时需要手动将它进一位
class Solution {
public int[] plusOne(int[] digits) {
for(int i = digits.length - 1; i >= 0; i--){
digits[i]++;
digits[i] %= 10;
if(digits[i] != 0){
return digits;
}
}
digits = new int[digits.length + 1];
digits[0] = 1;
return digits;
}
}
1.2 字符串加法
这道题主要的难点是9+1的进位,其他地方跟上面那个方式有点点像
这里通过一个变量add记录是否进位
class Solution {
public String addStrings(String num1, String num2) {
int i = num1.length() - 1, j = num2.length() - 1, add = 0;
StringBuffer ans = new StringBuffer();
while(i >= 0 || j >=0 || add != 0){
int x = i >= 0 ? num1.charAt(i) - '0' : 0;
int y = j >= 0 ? num2.charAt(j) - '0' : 0;
int result = x + y + add;
ans.append(result % 10);
add = result / 10;
i--;
j--;
}
ans.reverse();
return ans.toString();
}
}
1.3 二进制求和
这题跟上一题一样,也就一个9+1,一个是1+1
class Solution {
public String addBinary(String a, String b) {
StringBuilder ans = new StringBuilder();
int ca = 0;
for(int i = a.length() - 1, j = b.length() - 1;i >= 0 || j >= 0; i--, j--) {
int sum = ca;
sum += i >= 0 ? a.charAt(i) - '0' : 0;
sum += j >= 0 ? b.charAt(j) - '0' : 0;
ans.append(sum % 2);
ca = sum / 2;
}
ans.append(ca == 1 ? ca : "");
return ans.reverse().toString();
}
}
2. 幂运算
2.1 2 的幂
解题思路: 若 n=2^x 且 x 是自然数(即 n 是 2 的幂),则一定满足以下条件:
- 恒有 n & (n - 1) == 0,这是因为:
- n 二进制最高位为 1,其余所有位为 0;
- n-1 二进制最高位为 0,其余所有位为 1;
- 一定满足 n > 0。
因此,通过 n > 0 且 n & (n - 1) == 0 即可判定是否满足 n=2^x。
2^x | n (二进制) | n - 1 (二进制) | n & (n - 1) |
---|---|---|---|
2^0 | 0001 | 0000 | (0010) & (0001) == 0 |
2^1 | 0010 | 0001 | (0100) & (0011) == 0 |
2^2 | 0011 | 0010 | (1000) & (0111) == 0 |
2^3 | 0100 | 0011 | (0100) & (0101) == 0 |
class Solution {
public boolean isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
}
方法二:
通过不断除以2,直到n变成1或者不再能被2整除,然后检查最终的n是否等于1
class Solution {
public boolean isPowerOfTwo(int n) {
if (n == 0) {
return false;
}
while (n % 2 == 0) {
n /= 2;
}
return n == 1;
}
}
2.2 m的幂
上面是求2的幂,那么可以求m的幂
class Solution {
public boolean isPowerOfM(int n, int m) {
if (n == 0) {
return false;
}
while (n % m == 0) {
n /= m;
}
return n == 1;
}
}