算法通关村——数组实现加法和幂运算问题解析

1. 数组实现加法

1.1 加一

加一
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。

1.1.1 数组加法

这和正常的整数加法一样,都是先从最后一位进行遍历加上1,有了进位就标记,由于里面的元素都是1-9里面,所以只会产生10,通过%,就是0,那么只需要给前一位标记就行,但是如果首位是10了,那么就需要扩大数组长度,首位放1。

    public int[] plusOne(int[] digits) {
        int len = digits.length;
        for(int i = len-1;i>=0;i--){
            // 进位
            digits[i]++;
            // 取余数
            digits[i] %= 10;
            // 如果当前元素不是0,就表示没有进位,那么返回
            if(digits[i] != 0){
                return digits;
            }
        }
        // 首位需要进位,扩容
        digits = new int [len+1];
        digits[0] = 1;
        return digits;
    }

1.2 字符串相加

字符串相加
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = “11”, num2 = “123”
输出:“134”
示例 2:
输入:num1 = “456”, num2 = “77”
输出:“533”
示例 3:
输入:num1 = “0”, num2 = “0”
输出:“0”

1.2.1 逆序拼接字符串

依然是逆序字符串,然后将两个字符串相应位上的数进行相加,这里面需要加入一个add进位,最后将结果通过%得到当前的位数,通过/ 获取是否需要进位,最终的结果逆序就可以。

 public String addStrings(String num1, String num2) {
        int add = 0;
        StringBuilder sb = new StringBuilder();
        int i= num1.length()-1;
        int j =num2.length()-1;
        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 res = x+y+add;
            sb.append(res%10);
            add = res /10;
            i--;
            j--;
        }
        sb.reverse();
        return sb.toString();
    }

1.3 LCR 002. 二进制求和

二进制求和
给定两个 01 字符串 a 和 b ,请计算它们的和,并以二进制字符串的形式输出。

输入为 非空 字符串且只包含数字 1 和 0。

示例 1:

输入: a = “11”, b = “10”
输出: “101”
示例 2:

输入: a = “1010”, b = “1011”
输出: “10101”

1.3.1 逆序拼接字符串

这一题和上面一题一样,区别在于这里是2进制。

    public String addBinary(String a, String b) {
     int add =0;
        int i = a.length() - 1;
        int j = b.length() - 1;
        StringBuilder sb = new StringBuilder();
        while(i>=0 || j>=0 || add!=0){
            int x = i>=0 ? a.charAt(i) - '0' : 0;
            int y = j>=0 ? b.charAt(j) - '0' : 0;
            int res = x+y+add;
            sb.append(res%2);
            add = res/2;
            i--;
            j--;
        }
        sb.reverse();
        return sb.toString();
    }

2. 幂运算

2.1 2 的幂

2的幂
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。

如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

2.1.1 数学法

首先n小于等于0的肯定是需要排除的,接下来判断n%2 == 0,只有等于0,才意味着是2的幂,然后采用n = n/2,然后缩减n,只需要最后判断是不是1就可以。

   public boolean isPowerOfTwo(int n) {
        if(n<=0) return false;
        while(n%2==0){
            n/=2;
        }
        return n==1;
    }

2.1.2 位运算

因为是2的幂,所以二进制里面只有首位有一个1,其余位全部为0,所以可以采用n&(n-1)来判断是否为0,
例如 4 = 100 3 = 011 4 & 3 =0

    public boolean isPowerOfTwo(int n) {
        return n>0 && ( n&(n-1)) == 0;
    }

2.2 3的幂

给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。

整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3x

2.2.1 数学法

和2的一样

  public boolean isPowerOfThree(int n) {
        if(n<=0) return false;
        while(n%3 == 0){
            n/=3;
        }
        return n == 1;
    }

2.2.2 判断是否为最大3的幂数的约数

在int里面,最大是3 ^ 19, 所以只需要判断n是否为约数就可以。

 public boolean isPowerOfThree(int n) {
        return n > 0 && 1162261467 % n == 0;
    }

说实话,要找到int里面某个幂的最大值,有点不大现实。

2.3 4的幂

给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。

整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4x

2.3.1 数学法

   public boolean isPowerOfFour(int n) {
        if(n<=0) return false;
        while(n%4 == 0){
            n/=4;
        }
        return n==1;
    }

2.3.2 取模

由于4前面是3,而4%3 一定是1,那么4的幂%3一定是1,配合着2的幂 n&(n-1)使用.

   public boolean isPowerOfFour(int n) {
      return n>0 && (n&(n-1)) == 0 && (n%3 == 1);
    }

此方法甚妙。

你可能感兴趣的:(算法)