算法通关村第十三关——数字与数学白银挑战笔记

该部分主要针对数字加法问题和幂运算两个问题进行整理,归纳总结模板,能够早短时间内高校解决问题!

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,拜拜,第十三关第三幕见!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值