问题描述
给你一个长度为n的整数数组nums,其中n>1,输出数组output的所有值,其中output[i]等于nums中除nums[i]之外其余各元素的乘积。
输入格式:第一行为数组nums的长度n,第二行为数组num各元素
输出格式:数组output各元素
例如输入:
4
1 2 3 4
程序应该输出:
24 12 8 6
提示:题目数据保证数组之中任意元素的前缀元素和后缀元素(甚至整个数组)的乘积都在32位整数范围内。
说明:请不要使用除法,且在O(n)时间复杂度内完成此题。
进阶:
代码实现
import java.util.Scanner;
public class ArrayProduct {
public static void main(String[] args) {
//初始化nums数组
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = sc.nextInt();
}
sc.close();
//求output数组
int[] output = new int[n];
for (int i = 0; i < output.length; i++) { //枚举数组所有元素
int sum = 1; //存储出自己本身所有元素的积
for (int j = 0; j < nums.length; j++) {
if (j == i) { //两数组下标元素一样,跳过
continue;
}
sum *= nums[j];
}
output[i] = sum;
}
for (int i : output) { //打印结果
System.out.print(i + " ");
}
}
}
刚看到这道题时,就直接想到用两个for循环遍历除自身外所有元素相乘,但是题目要求时间复杂度为O(n),所以这样做显然不行,换一种思路,定义两个数组分别存储所有元素的前缀乘积和后缀乘积
import java.util.Scanner;
public class ArrayProduct {
public static void main(String[] args) {
//初始化nums数组
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = sc.nextInt();
}
sc.close();
//求output数组
int[] output = new int[n];
int[] left = new int[n]; //left[i]存储下标i左侧所有元素的积
int[] right = new int[n]; //right[i]存储下标i右侧所有元素的积
left[0] = 1; //第一个元素左侧没有元素,所以为1
for (int i = 1; i < left.length; i++) {
left[i] = nums[i - 1] * left[i - 1];
}
right[n - 1] = 1;//最后一个元素右侧没有元素,所以为1
for (int i = n - 2; i >= 0; i--) {
right[i] = nums[i + 1] * right[i + 1];
}
for (int i = 0; i < output.length; i++) {
output[i] = left[i] * right[i]; //结果为左侧元素之积乘右侧元素之积
}
for (int i : output) { //打印结果
System.out.print(i + " ");
}
}
}
上述代码优化了时间复杂度,但是写着有些麻烦,还可以继续优化,直接用output数组左右开弓
import java.util.Scanner;
public class ArrayProduct {
public static void main(String[] args) {
//初始化nums数组
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = sc.nextInt();
}
sc.close();
//求output数组
int[] output = new int[n];
for (int i = 0; i < output.length; i++) {
output[i] = 1; //先将所有元素初始化成1,方便乘积
}
int left = 1; //left存储左侧所有元素的积
int right = 1; //right存储右侧所有元素的积
for (int i = 0; i < output.length - 1; i++) {
left *= nums[i];
right *= nums[n - i - 1];
output[i + 1] *= left;
output[n - i - 2] *= right;
}
for (int i : output) { //打印结果
System.out.print(i + " ");
}
}
}