LeetCode043——字符串相乘

版权声明:版权所有,转载请注明原网址链接。 https://blog.csdn.net/qq_41231926/article/details/82710845

我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/multiply-strings/description/

题目描述:

知识点:字符串

思路:模拟手工算法

本题的思路很简单,就是单纯地模拟手工算法得出结果,但想把这个程序写得优美还是有难度的,下面将罗列我自己写程序时的一个个不同的实现版本。

版本一:

逻辑如下:

(1)数组stringBuilders里存储的是字符串num2中的各位上的数和num1相乘的结果,比如对于123 * 456而言,其存储的就是738,615,492。

(2)给数组stringBuilders中的元素添0,使其成为738,6150,49200。

(3)反转stringBuilders中的元素,使其成为837,0516,00294。

(4)对stringBuilders中的元素进行相加操作,使其成为88065。

(5)反转(4)中的结果,得到最终答案56088。

注意,在程序开始时,需要对乘数为0的情况做特殊处理,否则会出现类似0000的答案。

时间复杂度是O(n1 * n2),其中n1为字符串num1的长度,n2为字符串num2的长度。实现过程中使用了一个长度为n2的StringBuilder类型的数组,而数组中每个元素的长度是n1或者n1 + 1,因此空间复杂度为O(n1 * n2)。

JAVA代码:

public class Solution {

	public String multiply(String num1, String num2) {
        int n1 = num1.length();
        int n2 = num2.length();
        if(n1 == 1 && Integer.parseInt(num1) == 0) {
        	return num1;
        }
        if(n2 == 1 && Integer.parseInt(num2) == 0) {
        	return num2;
        }
        StringBuilder result = new StringBuilder();
        StringBuilder[] stringBuilders = new StringBuilder[n2];
        for (int i = n2 - 1; i >= 0; i--) {
			StringBuilder stringBuilder = new StringBuilder();
			int flag = 0;
			for (int j = n1 - 1; j >= 0; j--) {
				Integer integer = Integer.parseInt(num1.substring(j, j + 1)) * Integer.parseInt(num2.substring(i, i + 1));
				stringBuilder.append((integer + flag) % 10);
				flag = (integer + flag) / 10;
			}
			if(flag > 0) {
				stringBuilder.append(flag);
			}
			stringBuilders[n2 - i - 1] = stringBuilder.reverse();
		}
        for (int i = 0; i < n2; i++) {
        	for (int j = 0; j < i; j++) {
        		stringBuilders[i].append(0);
			}
        }
        for (int i = 0; i < n2; i++) {
        	stringBuilders[i] = stringBuilders[i].reverse();
        }
        int flag = 0;
        int maxLen = 0;
        for (int i = 0; i < n2; i++) {
        	maxLen = Math.max(maxLen, stringBuilders[i].length());
        }
        for (int i = 0; i < maxLen; i++) {
			int sum = 0;
			for (int j = 0; j < n2; j++) {
				if(i < stringBuilders[j].length()) {
					sum += Integer.parseInt(stringBuilders[j].substring(i, i + 1));
				}
			}
			int num = (sum + flag) % 10;
			flag = (sum + flag) / 10;
			result.append(num);
		}
        if(flag > 0) {
        	result.append(flag);
        }
        return result.reverse().toString();
    }
}

LeetCode解题报告:

版本二:

在版本一的逻辑中,我们前前后后对数组stringBuilders中的元素翻转了共3次,那么,肯定有可以简化的地方。版本二在版本一的基础上省去其中的2次翻转。

JAVA代码:

public class Solution {

	public String multiply(String num1, String num2) {
        int n1 = num1.length();
        int n2 = num2.length();
        if(n1 == 1 && Integer.parseInt(num1) == 0) {
        	return num1;
        }
        if(n2 == 1 && Integer.parseInt(num2) == 0) {
        	return num2;
        }
        StringBuilder result = new StringBuilder();
        StringBuilder[] stringBuilders = new StringBuilder[n2];
        for (int i = n2 - 1; i >= 0; i--) {
			StringBuilder stringBuilder = new StringBuilder();
			int flag = 0;
			for (int j = n1 - 1; j >= 0; j--) {
				Integer integer = Integer.parseInt(num1.substring(j, j + 1)) * Integer.parseInt(num2.substring(i, i + 1));
				stringBuilder.append((integer + flag) % 10);
				flag = (integer + flag) / 10;
			}
			if(flag > 0) {
				stringBuilder.append(flag);
			}
			stringBuilders[n2 - i - 1] = stringBuilder;
		}
        for (int i = 0; i < n2; i++) {
        	for (int j = 0; j < i; j++) {
        		stringBuilders[i] = stringBuilders[i].insert(0, "0");
			}
        }
        int flag = 0;
        int maxLen = 0;
        for (int i = 0; i < n2; i++) {
        	maxLen = Math.max(maxLen, stringBuilders[i].length());
        }
        for (int i = 0; i < maxLen; i++) {
			int sum = 0;
			for (int j = 0; j < n2; j++) {
				if(i < stringBuilders[j].length()) {
					sum += Integer.parseInt(stringBuilders[j].substring(i, i + 1));
				}
			}
			int num = (sum + flag) % 10;
			flag = (sum + flag) / 10;
			result.append(num);
		}
        if(flag > 0) {
        	result.append(flag);
        }
        return result.reverse().toString();
    }
}

LeetCode解题报告:

版本三:

去除版本二中给数组stringBuilders中的元素插入0的操作。

JAVA代码:

public class Solution {

	public String multiply(String num1, String num2) {
        int n1 = num1.length();
        int n2 = num2.length();
        if(n1 == 1 && Integer.parseInt(num1) == 0) {
        	return num1;
        }
        if(n2 == 1 && Integer.parseInt(num2) == 0) {
        	return num2;
        }
        StringBuilder result = new StringBuilder();
        StringBuilder[] stringBuilders = new StringBuilder[n2];
        for (int i = n2 - 1; i >= 0; i--) {
			StringBuilder stringBuilder = new StringBuilder();
			int flag = 0;
			for (int j = n1 - 1; j >= 0; j--) {
				Integer integer = Integer.parseInt(num1.substring(j, j + 1)) * Integer.parseInt(num2.substring(i, i + 1));
				stringBuilder.append((integer + flag) % 10);
				flag = (integer + flag) / 10;
			}
			if(flag > 0) {
				stringBuilder.append(flag);
			}
			stringBuilders[n2 - i - 1] = stringBuilder;
		}
        int flag = 0;
        for (int i = 0; i < stringBuilders[n2 - 1].length() + n2 - 1; i++) {
			int sum = 0;
			for (int j = 0; j < n2; j++) {
				if(i - j < stringBuilders[j].length() && i - j >= 0) {
					sum += Integer.parseInt(stringBuilders[j].substring(i - j, i - j + 1));
				}
			}
			int num = (sum + flag) % 10;
			flag = (sum + flag) / 10;
			result.append(num);
		}
        if(flag > 0) {
        	result.append(flag);
        }
        return result.reverse().toString();
    }
}

LeetCode解题报告:

版本四:

StringBuilder类的使用,能够方便我们写程序,但是会降低程序运行速度,因此我们舍弃之。

JAVA代码:

public class Solution {

	public String multiply(String num1, String num2) {
        int n1 = num1.length();
        int n2 = num2.length();
        char[] array1 = num1.toCharArray();
        char[] array2 = num2.toCharArray();
        if(array1[0] == '0' || array2[0] == '0') {
        	return "0";
        }
        String[] strings = new String[n2];
        for (int i = n2 - 1; i >= 0; i--) {
        	String string = "";
			int flag = 0;
			for (int j = n1 - 1; j >= 0; j--) {
				int num = (array1[j] - '0') * (array2[i] - '0');
				string += (num + flag) % 10;
				flag = (num + flag) / 10;
			}
			if(flag > 0) {
				string += flag;
			}
			strings[n2 - i - 1] = string;
		}
        String result = "";
        int flag = 0;
        for (int i = 0; i < strings[n2 - 1].length() + n2 - 1; i++) {
			int sum = 0;
			for (int j = 0; j < n2; j++) {
				if(i - j < strings[j].length() && i - j >= 0) {
					sum += strings[j].charAt(i - j) - '0';
				}
			}
			int num = (sum + flag) % 10;
			flag = (sum + flag) / 10;
			result = num + result;
			
		}
        if(flag > 0) {
        	result = flag + result;
        }
        return result;
    }
}

LeetCode解题报告:

版本五:

对于字符串num2中的每一位数与字符串num1相乘所得的结果,不再分开计算最后相加,而是先全部累加,最后再考虑进位的影响。对于最终结果的第i + j位数,可以由num1数组的第i位数和num2数组的第j位数组成

JAVA代码:

public class Solution {

	public String multiply(String num1, String num2) {
        int n1 = num1.length();
        int n2 = num2.length();
        if(n1 == 1 && Integer.parseInt(num1) == 0) {
        	return num1;
        }
        if(n2 == 1 && Integer.parseInt(num2) == 0) {
        	return num2;
        }
        int[] nums = new int[n1 + n2];
        String result = "";
        for (int i = 0; i < n1; i++) {
			for (int j = 0; j < n2; j++) {
				nums[i + j] += (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
			}
		}
        int flag = 0;
        for (int i = n1 + n2 - 2; i >= 0; i--) {
			result = (nums[i] + flag) % 10 + result;
			flag = (nums[i] + flag) / 10;
		}
        if(flag > 0) {
        	result = flag + result;
        }
        return result;
    }
}

LeetCode解题报告:

猜你喜欢

转载自blog.csdn.net/qq_41231926/article/details/82710845
今日推荐