解决力扣字符串相加和相乘问题

目录

今日良言:花有重开日,人无再少年

一、字符串相加

1.问题描述

2.解决思路

3.代码实现

4.题目链接

5.相似题目

二、字符串相乘

1.问题描述

2.解决思路

3.代码实现

4.题目链接


今日良言:花有重开日,人无再少年

一、字符串相加

1.问题描述

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

例如:

输入:num1 = "11", num2 = "123"
输出:"134"

2.解决思路

a. 题目要求不可以使用库,以及不能直接将输入的字符串换成整数形式,所以说我们放弃这种思路。

b.首先针对相加问题,我们要先考虑进位的问题,从后向前进位,那么我们不妨将两个字符串从后向前加,每次拿到两个字符串的下标的字符,然后转成整数,注意:我们需要考虑两个字符串不相等的情况,所以用一个下表来表示两个字符串显然是不行的,那么我们使用 i 和 j 两个变量来表示下标,i 和 j  的初始值就是两个字符串的长度-1 。

c.那么确定了下标以后,我们需要考虑,如果有一个字符串为空了,该如何计算?  实际上,我们可以将为空的那个字符串(也就是 i 或者 j  < 0)的字符直接当作0即可,即使参与运算也不会影响结果。

d.假设此时两个字符串的下标都合法,对应的值为x和y,那么将其转换成数字以后,我们需要考虑进位,因此我们设置一个变量 add 表示每次需要向前进位的数字,也就是 add =(x + y)/ 10 。

e.我们使用StringBuffer来进行字符串拼接,那么我们每次拼接的值是多少呢?实际上当前x+y+add(向前进位的值)% 10 就是我们需要拼接的值。

f.不难看出,上述操作实际上是一个循环,条件是 i >=0 || j>=0 || add > 0     add这个条件存在的意思是:可能最后相加的结果还是要向前进位,我们不能舍去这个进位的值。

3.代码实现

class Solution {
    public String addStrings(String num1, String num2) {
      // 从下标最高位开始计算,用add记录两数相加的结果是否需要进位
       int i = num1.length() - 1;
       int j = num2.length() - 1;
       int add = 0;
       // 如果有一个下标不为0或者add也就是需要进位 就一直循环
       StringBuffer str = 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; // 需要加上进位的数字
           str.append(result % 10); 
           add = result / 10;
           i--;
           j--;
       }
       // 计算后要翻转
       str.reverse();
       return str.toString();
}

4.题目链接

415. 字符串相加 - 力扣(LeetCode)

5.相似题目

链接:67. 二进制求和 - 力扣(LeetCode)

解法:

class Solution {
    public String addBinary(String a, String b) {
        int i = a.length() - 1;
        int j = b.length() - 1; // i j都是下标
        int add = 0; // 进位的数字
        StringBuffer str =  new StringBuffer();
        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 result = x + y +add;
            str.append(result % 2);
            add = result / 2;
            i--;
            j--;
        }
        str.reverse();
        return str.toString();
    }
}

二、字符串相乘

1.问题描述

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

例如:

输入: num1 = "123", num2 = "456"
输出: "56088"

2.解决思路

a.字符串相乘无法直接使用字符串相加的计算方式。首先,我们需要观察一个规律,如下图:

 这里num1和num2是需要计算的字符串中的数字,result是我们创建的需要存储的计算结果。观察上述下标,有什么发现?  假设 i 是num1的下标,j 是 num2的下标, num1[i] * num2[j] 的结果在result[i+j] 中。

b.首先我们可以创建一个两个字符串长度相加的长度的数组result用于存储计算结果,假设num1的长度为n,num2的长度为m,那么创建的result容纳的数据就是m+n 个,为什么创建m+n呢?因为,假设都是多大的两位数99相乘,他们的计算结果的长度一定不比m+n大。

c.如果只是将两个字符串每个位置的计算结果都放在 result的 i + j 下标处的话,那么最高位的进位就会被忽略,所以说,我们不妨空出来一个位置存放需要像最高位进的那个值。 用代码实现就是:  result[i + j + 1] = num1[i] + num2[j];   

d.然后我们需要考虑进位的问题,从后向前遍历result数组,满10就进位。

e.进位结束后,我们创建一个 StringBuffer 类型的 str 用来拼接result中的计算结果,但是,由于之前我们将result的0下标空了出来,如果没有向0下标进位,那么该位置就应该删除,所以我们需要考虑是否删除该下标处的值。

f.最后将其转换成字符串返回即可 

3.代码实现

class Solution {
    public String multiply(String num1, String num2) {
     if (num1.equals("0") || num2.equals("0"))
      return "0";
      char[] arr1 = num1.toCharArray();
      char[] arr2 = num2.toCharArray();
      int n = arr1.length;
      int m = arr2.length;
      int[] result = new int[m+n];
      for (int i = 0; i < n; i++) {
          for (int j = 0; j < m; j++) {
              result[i+j+1] += ((arr1[i]-'0')*(arr2[j]-'0'));
          }
      }
      // 从后往前处理进位
      for(int j = result.length-1; j > 0; j--) {
          if (result[j] >= 10) {
              result[j-1] += result[j]/10;
              result[j] = result[j] % 10;
          }
      }
      // 如果没有进位的话,我们需要去掉0
      StringBuilder str = new StringBuilder();
      for (int i : result) {
          str.append(i);
      }
      if (str.charAt(0) == '0') {
          str.deleteCharAt(0);
      }
      return str.toString();
    }
}

4.题目链接

43. 字符串相乘 - 力扣(LeetCode)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值