leetcode415-字符串相加&拓展题36进制加法

一.题目描述

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。

提示:

num1 和num2 的长度都小于 5100
num1 和num2 都只包含数字 0-9
num1 和num2 都不包含任何前导零
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式

二.题目解析

public static String addStrings(String num1, String num2) {
        /*双指针法*/
        int i = num1.length() - 1;
        int j = num2.length() - 1;
        //cur表示当前位的相加之和,add表示当前位产生的进位
        int add = 0,cur = 0,number1,number2;
        StringBuilder stringBuilder = new StringBuilder("");
        //从最后一位开始计算
        while (i >= 0 && j >= 0){
            //ASCII 码相减,得到字符对应的 int 数值
            number1 = num1.charAt(i) - '0';
            number2 = num2.charAt(j) - '0';
            cur = number1 + number2 + add;
            add = cur / 10;
            cur = cur % 10;
            stringBuilder.append(cur);
            //向前遍历
            i--;
            j--;
        }
        //两个字符串长度不相等,短的先遍历完,剩下的只需要在长的剩余部分计算
        while (i >= 0){
            cur = num1.charAt(i) - '0' + add;
            add = cur / 10;
            cur = cur % 10;
            stringBuilder.append(cur);
            i--;
        }
        while (j >= 0){
            cur = num2.charAt(j) - '0' + add;
            add = cur / 10;
            cur = cur % 10;
            stringBuilder.append(cur);
            j--;
        }

在这里插入图片描述
2.1中的代码冗余在对两个字符串长度的判断,和遍历完成时头部是否添加进位1的判断
代码还可以进一步优化:

public String addStrings1(String num1, String num2) {
        /*双指针法,第一个方法的精简版
        * 时间复杂度 O(max(M,N)),取较长字符串的长度
        * 空间复杂度O(1):指针与变量使用常数大小空间
        * */
        StringBuilder res = new StringBuilder("");
        int i = num1.length() - 1, j = num2.length() - 1, carry = 0;
        //while循环也兼容两个字符串都遍历完产生进位的情形
        while(i >= 0 || j >= 0 || carry != 0){
            //长度较短的字符串溢出索引位置填充为0,便于计算
            int n1 = i >= 0 ? num1.charAt(i) - '0' : 0;
            int n2 = j >= 0 ? num2.charAt(j) - '0' : 0;
            int tmp = n1 + n2 + carry;
            carry = tmp / 10;
            res.append(tmp % 10);
            i--; j--;
        }
        return res.reverse().toString();
    }

在这里插入图片描述
3.考虑到栈的先进后出特性,我们还可以利用栈来依次保存,以实现“翻转”的效果

public String addStrings2(String num1, String num2) {
        /*双指针法,利用栈翻转*/
        StringBuilder res = new StringBuilder("");
        Stack<Integer> stack = new Stack<>();
        int i = num1.length() - 1, j = num2.length() - 1, carry = 0;
        while(i >= 0 || j >= 0 || carry != 0){
            int n1 = i >= 0 ? num1.charAt(i) - '0' : 0;
            int n2 = j >= 0 ? num2.charAt(j) - '0' : 0;
            int tmp = n1 + n2 + carry;
            carry = tmp / 10;
            stack.push(tmp % 10);
            i--; j--;
        }
        while (!stack.isEmpty()){
            res.append(stack.pop());
        }
        return res.toString();
    }

在这里插入图片描述



拓展:36进制加法

题目描述

36进制由0-9,a-z,共36个字符表示。

要求按照加法规则计算出任意两个36进制正整数的和,如1b + 2x = 48 (解释:47+105=152)

要求:不允许使用先将36进制数字整体转为10进制,相加后再转回为36进制的做法

思路:采用方式2(把10进制改成36进制即可):

/**
 leetcode415拓展
 36进制加法
 */
public class Solution8 {
    public String addBase36Strings(String num1, String num2) {
        /*双指针法,第一个方法的精简版
         * 时间复杂度 O(max(M,N)),取较长字符串的长度
         * 空间复杂度O(1):指针与变量使用常数大小空间
         * */
        StringBuilder res = new StringBuilder("");
        int i = num1.length() - 1, j = num2.length() - 1, carry = 0;
        //while循环也兼容两个字符串都遍历完产生进位的情形
        while(i >= 0 || j >= 0 || carry != 0){
            //长度较短的字符串溢出索引位置填充为0,便于计算
            int n1 = i >= 0 ? getBase36Int(num1.charAt(i)) : 0;
            int n2 = j >= 0 ? getBase36Int(num2.charAt(j)) : 0;
            int tmp = n1 + n2 + carry;
            carry = tmp / 36;
            //该位上计算得到的数字转为36进制字符
            res.append(getBase36Char(tmp % 36));
            i--; j--;
        }
        return res.reverse().toString();
    }

    char getBase36Char(int n){
        /*36进制数字转字符类型*/
        if(n <= 9){
            return (char)(n + '0');
        }
        return (char)(n - 10 + 'a');
    }

    int getBase36Int(char ch){
        /*36进制字符转数字*/
        if(ch <= '9'){
            return ch - '0';
        }
        return ch - 'a' + 10;
    }

    public static void main(String[] args) {
        Solution8 s8 = new Solution8();
        System.out.println(s8.addBase36Strings("1c","zi"));
        System.out.println(s8.addBase36Strings("mz7","gw"));
    }

}

运行:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值