1. 字符串数字相加
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
解法一
因为是字符串数字,如果字符串太长,可能直接导致int或long溢出。因此需要用竖式计算,用数组计算每位相乘得到的结果,可以先采用累加的方式,最后再统一进位计算。
例如:789 * 6 = 【42,48,54】,最后再统一进位,【4,7,3,4】
class Solution {
public String multiply(String num1, String num2) {
int len1 = num1.length();
int len2 = num2.length();
if(num1.equals("0") || num2.equals("0")) return "0";
int[] result = new int[len1+len2];
//每个槽中进行累加
for(int i = len1-1; i >= 0; i-- ){
for(int j = len2-1; j >= 0 ; j--){
result[j+i+1] += (num1.charAt(i) - '0')*(num2.charAt(j) - '0');//注意j+i+1才是index
}
}
//进行进位计算
int count = 0;
for(int i = len1+len2-1; i >= 0; i--){
if(result[i] + count >= 10){
result[i] += count;//进位
count = result[i] / 10;
result[i] = result[i] % 10;
}else{
result[i] += count;
count = 0;
}
}
//转换成字符串
StringBuilder sb = new StringBuilder();
boolean flag = false;
for(int i = 0; i < len1+len2; i++){
if( !flag && result[i] > 0){
flag = true;
}
if(flag){
sb.append(result[i]);
}
}
return sb.toString();
}
}
2. Z字形变换
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
解法一
维持一个StringBuilder数组,遍历字符串,首先从上到下依次放入字符到StringBuilder中,当字符串索引到底时(numRows)则开始反向,从下到上放置字符到StringBuilder的尾部,如此反复即可。
abcdefghi 3
a e i
b d f h
c g
class Solution {
public String convert(String s, int numRows) {
if(numRows == 1) return s;
StringBuilder[] sarr = new StringBuilder[numRows];
for(int i = 0; i < numRows ; i++){
sarr[i] = new StringBuilder();
}
int index = 0;
boolean direct = false;
int len = s.length();
for(int i = 0; i < len; i++){
sarr[index].append(s.charAt(i));
if(!direct){//反向
if(index == numRows - 1){
direct = true;
index = numRows - 2;
}else{
index++;
}
}else{//反向
if(index == 0){
direct = false;
index = 1;
}else{
index--;
}
}
}
StringBuilder result = new StringBuilder();
for(StringBuilder sb : sarr){
result.append(sb);
}
return result.toString();
}
}
3. 整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
解法一
利用取余和除法,依次取出最后一位数,然后与新数相加,每次新数都要乘以10。注意溢出问题。
两边都除以10,即可得到新的判断式,且保证中间值不溢出32位数范围
123
3
310 + 2
(310+2)* 10 + 1 = 321
class Solution {
public int reverse(int x) {
int tmp = 0;
int result = 0;
while(x != 0){
if(result < Integer.MIN_VALUE / 10 || result > Integer.MAX_VALUE/10) return 0;
tmp = x % 10;
x = x / 10;
result = result*10 + tmp;
}
return result;
}
}
4. 字符串转换整数 (atoi)
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数。
函数 myAtoi(string s) 的算法如下:
空格:读入字符串并丢弃无用的前导空格(" ")
符号:检查下一个字符(假设还未到字符末尾)为 ‘-’ 还是 ‘+’。如果两者都不存在,则假定结果为正。
转换:通过跳过前置零来读取该整数,直到遇到非数字字符或到达字符串的结尾。如果没有读取数字,则结果为0。
舍入:如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被舍入为 −231 ,大于 231 − 1 的整数应该被舍入为 231 − 1 。
返回整数作为最终结果。
解题一
这题最主要是要读懂题意:遇到空格就跳过,遇到数字就开始计数,遇到-+就开始计数,如果空格-+排除后计数前遇到其他字符,则返回0;否则直接开始计数。计数时需要考虑之前的正负号。如果计数后遇到数字之外的其他字符,则直接返回结果。如果数字超过32位有符号整数的范围,则返回对应的边界值。
class Solution {
public int myAtoi(String s) {
if(s.equals("")) return 0;
//首先去除空格
int index = 0;
while(index < s.length() && s.charAt(index) == ' ') index++;
if(index == s.length()) return 0;
int sign = 1;//正负标志位
if(s.charAt(index) == '-'){
sign = -1;
index++;
}else if(Character.isLetter(s.charAt(index))){
return 0;
}else if(s.charAt(index) == '+'){
index++;
}
long result = 0;
for(int i = index ; i < s.length(); i++){
if(!Character.isDigit(s.charAt(i))){
return (int)result;
}
result = result*10 + sign*(s.charAt(i) - '0');
if(result > Integer.MAX_VALUE ) return Integer.MAX_VALUE;
if(result < Integer.MIN_VALUE) return Integer.MIN_VALUE;
}
return (int)result;
}
}