该部分主要针对数字加法问题和幂运算两个问题进行整理,归纳总结模板,能够早短时间内高校解决问题!
1.数字加法专题
1.1数组实现整数加法
题目见LeetCode66,表述为:数字由数组给定,将该数字加1并返回。
题目分析,本道题目只需要将数字加1返回即可,因此只需要关注进位情况,特别需要关注最高位进位情况!当数组第i位发生进位时,第i-1位必然产生进位,该进位可以像“多米诺骨牌”一样一直向前传递,一直传递到数组发生越界。
那么如何解决这一问题呢?很简单开一个arr.lengh+1长度的新数组,将新数组的第0位置设置成1,即可解决!
此外,多米诺骨牌传递的时候,当一处发生断裂,传递不在继续。那么同理,当第i-1位接收了第i位的进位,但是其本身没有发生进位情况时,直接返回数组即可,就是最终答案!
厘清思路,直接上代码!
public static int[] myPlusOne(int[] digits) {
int len = digits.length;
for (int i = len - 1; i >= 0; i--) {
digits[i]++;
digits[i] %= 10;
if(digits[i] != 0){
return digits;
}
}
digits = new int[len+1];
digits[0] = 1;
return digits;
}
1.2字符串加法
对于加法问题,我们有加法解题模板!
首先,定义进位位add,然后,维护两个指针ij分别指向两个字符串的末尾,再设置ans保存加法结果。
从末尾向前依次遍历每一个字符,遍历过程中,需要确定参加加法运算的两个数字xy以及前一位的进位add,并将它们累加,然后求出本位数字结果和进位位,分别保存到ans和add中。依次进行上述操作,完成字符串遍历即可!【特别注意:当遍历过程中一个字符串发生越界时,只需要将xy中发生越界的那一个置为0,不参与加法运算即可!】
最后,判断加法结果ans是否需要添加最后的进位位add,再反转加法结果ans即可!
厘清思路,直接上代码!
public static String myAddStrings(String num1, String num2) {
//进位
int add = 0;
//维护ij指向字符串末尾
int i = num1.length() - 1, j = num2.length() - 1;
StringBuffer ans = new StringBuffer();
while(i >= 0 || j >= 0){
int x = i >= 0 ? num1.charAt(i) - '0' : 0;
int y = j >= 0 ? num2.charAt(j) - '0' : 0;
ans.append((x + y + add) % 10);
add = (x + y + add) / 10;
i--;
j--;
}
if(add != 0) ans.append(add);
return ans.reverse().toString();
}
1.3二进制加法
题目见LeetCode67,本道题目本质上还是属于字符串加法,归根到底是属于数组加法,因此,可以使用1.2中数组加法模板,来!再次巩固模板吧!
直接上代码!
public static String myAddBinary(String a, String b) {
int add= 0;
int i = a.length() - 1;
int j = b.length() - 1;
StringBuilder ans = new StringBuilder();
while(i >= 0 || j >= 0){
int x = i >= 0 ? a.charAt(i) - '0' : 0;
int y = j >=0 ? b.charAt(j) - '0' : 0;
int result = x + y + add;
ans.append(result % 2);
add = result / 2;
i--;
j--;
}
ans.append(add == 1 ? 1 : "");
return ans.reverse().toString();
}
2.幂运算
该专题的幂运算指的是,判断一个数是不是一个特定正整数的整数次幂。
幂运算涉及两类解题方法,第一类方法是通用解题模板(必须掌握),第二类方法针对于判断是不是素数的整数次幂(理解之后也易于掌握)!
2.1求2的幂
题目见LeetCode231,描述为给定正整数n,判断其是否是2的幂次方。
如果n是2的整数次幂,那么再使用“短除法”过程中,依次除2,总是最后一次商为1,反过来思考n== 1*2*2*2*...*2,那么幂次方解题模板呼之欲出!
首先,0和负数显然不是2的整数次幂!
如果该数字能够被2整除,那么就除2,当不能被2整除时,当且仅当这个数字为1,它就是2的整数次幂(K的整数次幂也是同样的道理!)直接上代码!
public static boolean myIsPowerOfTwo(int n) {
if(n <= 0) return false;
while(n % 2 == 0){
n /= 2;
}
return n == 1;
}
当然,还可以使用位运算来考虑问题,如果一个数字是2的整数次幂,那么它一定是1、10、100、1000...这样的形式,那么我们只需要采用位运算中的技巧n&(n-1)即可让最后一个1变成0,在判断变换后的数字是否为0,即可判断它是否是2的整数次幂了!直接上代码!
public static boolean myIsPowerOfTwo2(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
2.2求3的幂
采用3的整数次幂模板,解决该问题!直接上代码!
public static boolean myIsPowerOfThree(int n) {
if(n <= 0) return false;
while(n % 3 == 0){
n /= 3;
}
return n == 1;
}
此外,素数也有自己的整数次幂解决办法!
首先找到不发生越界的3的最大次幂,也就是1162261467。
如果n是3的整数次幂,那么该数字一定可以将1162261467整除;如果n不是3的整数次幂,比如6那么该数字出的结果就是3^18/2,则n一定不是整数,利用这个特性进行判断!直接上代码!
public static boolean myIsPowerOfThree2(int n) {
return n > 0 && 1162261467 % n == 0;
}
2.3求4的幂
采用4的整数次幂模板,相信你也能解决该问题!尝试一下吧!
OK,《算法通关村第十三关——数字与数学白银挑战笔记》结束,喜欢的朋友三联加关注!关注鱼市带给你不一样的算法小感悟!(幻听)
再次,感谢鱼骨头教官的学习路线!鱼皮的宣传!小y的陪伴!ok,拜拜,第十三关第三幕见!