算法之字符串

1、字符串相加

简单

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

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

示例 1:

复制代码
输入:num1 = "11", num2 = "123"
输出:"134"

示例 2:

复制代码
输入:num1 = "456", num2 = "77"
输出:"533"

示例 3:

复制代码
输入:num1 = "0", num2 = "0"
输出:"0"

思路

1、题目要求需要给字符串中的数字相加,就要考虑到进位

2、要给一个字符串拆分成单个字符

3、单个字符相加就要考虑到需要将字符转换为数字

4、相加操作要从两个字符串的末尾出发,要考虑两个字符串的长度,以及相加之后的反转

解题

java 复制代码
class Solution {
    public String addStrings(String num1, String num2) {
        int l1 = num1.length() - 1, l2 = num2.length() - 1, add = 0;
      	StringBuilder sb = new StringBuilder();
      
      	while (l1 >= 0 || l2 >= 0 || add != 0) {
          int x = l1 >= 0 ? num1.charAt(l1) - '0' : 0;
          int y = l2 >= 0 ? num2.charAt(l2) - '0' : 0;
          
          int sum = x + y + add;
          
          sb.append(sum % 10);
          add = sum / 10;
          
          l1 --;
          l2 --;
        }
      	
      	return sb.reverse().toString();
    }
}

考察

1、使用StringBuilder的构建字符串

2、注意计算是从后往前的,所以最后要反转字符串

2、二进制求和

简单

给你两个二进制字符串 ab ,以二进制字符串的形式返回它们的和。

示例 1:

复制代码
输入:a = "11", b = "1"
输出:"100"

示例 2:

复制代码
输入:a = "1010", b = "1011"
输出:"10101"

提示:

  • 1 <= a.length, b.length <= 104
  • ab 仅由字符 '0''1' 组成
  • 字符串如果不是 "0" ,就不含前导零

思路

与第一题的思路一致,就是十进制换成了二进制,可以当作练习

解题

java 复制代码
class Solution {
    public String addBinary(String a, String b) {
        int l1 = a.length() - 1, l2 = b.length() - 1, add = 0;
      	StringBuilder sb = new StringBuilder();
      
      	while (l1 >= 0 || l2 >= 0 || add != 0) {
          int x = l1 >= 0 ? a.charAt(l1) - '0' : 0;
          int y = l2 >= 0 ? b.charAt(l2) - '0' : 0;
          
          int sum = x + y + add;
          
          sb.append(sum % 2);
          add = sum / 2;
          
          l1 --;
          l2 --;
        }
      	
      	return sb.reverse().toString();
    }
}

考察

和上题类似

3、字符串相乘

中等

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

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

示例 1:

复制代码
输入: num1 = "2", num2 = "3"
输出: "6"

示例 2:

复制代码
输入: num1 = "123", num2 = "456"
输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200
  • num1num2 只能由数字组成。
  • num1num2 都不包含任何前导零,除了数字0本身。

思路

1、模拟竖式乘法,也是要从一个数的最后一位乘另一个数

2、定一个数组,存储当前位置的值还有上一个位置进值,注意每次计算该单位数值之前要累加上数组中该位置之前的值

3、使用StringBuilder对数组中的数进行拼接,注意从前往后要考虑首位的0

4、数组的位数最大就是两个数的位数和

5、根据乘法中的0*任何值都等于0,需要针对这种情况作处理

解题

java 复制代码
class Solution {
    public String multiply(String num1, String num2) {
        if(num1.equals("0") || num2.equals("0")) {
            return "0";
        }

        int n1 = num1.length(), n2 = num2.length(), sum = 0;
      	int[] result = new int[n1 + n2];
      
      	for(int i = n1 - 1; i >= 0; i--) {
          for(int j = n2 - 1; j >= 0; j--) {
            int a = num1.charAt(i) - '0';
            int b = num2.charAt(j) - '0';
            sum = a * b;
            
            // 对应数组当前位置的索引
            int p1 = i + j + 1;
            // 上一个位置的索引
            int p2 = i + j;
            
            sum += result[p1];
            
            result[p1] = sum % 10;
            result[p2] += sum / 10;
          }
        }
      	StringBuilder sb = new StringBuilder();
      	for(int num : result) {
          if(!(sb.length() == 0 && num == 0)) {
            	sb.append(num);
          }
        }
      	
      return sb.toString();
    }
}

4、验证回文串

简单

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false

示例 1:

复制代码
输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。

示例 2:

复制代码
输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。

示例 3:

复制代码
输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。

思路

1、需要给原始字符串中的标点空格去掉,转成一个字符串

2、比较转好的字符串和反转后的字符串,返回布尔值

解题

java 复制代码
class Solution {
    public boolean isPalindrome(String s) {
        int l = s.length();
      	StringBuilder sb = new StringBuilder();
      	
      	for(int i = 0; i < l; i++) {
          char ch = s.charAt(i);
          if(Character.isLetterOrDigit(ch)) {
            sb.append(Character.toLowerCase(ch));
          }
        }
      	
      	StringBuilder resb = new StringBuilder(sb).reverse();
      	return sb.toString().equals(resb.toString());
    }
}

考察

1、Character对应的方法.isLetterOrDigit().toLowerCase()

2、使用StringBuilder.reverse()反转链表匹配是否是回文