给定长度为 n 的整数数组 nums
,其中 n > 1,返回输出数组 output
,其中 output[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积。
示例:
输入:[1,2,3,4]
输出:[24,12,8,6]
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
class Solution {
public int[] productExceptSelf(int[] nums) {
if (nums == null || nums.length < 2) {
return nums;
}
long product = 1;
int zeroCount = 0;
for (int i = 0; i < nums.length; ++i) {
if (nums[i] == 0) {
++zeroCount;
} else {
product *= nums[i];
}
}
int[] result = new int[nums.length];
for (int i = 0; i < result.length; ++i) {
if (zeroCount > 1) {
result[i] = 0;
} else if (zeroCount == 1) {
if (nums[i] == 0) {
result[i] = (int) product;
} else {
result[i] = 0;
}
} else {
result[i] = (int) product / nums[i];
}
}
return result;
}
}
注意边界条件。分三种情况讨论。数组有两0,有一0,没0.
思考,作为参数的数组,是否是对象,如果以参数nums作为结果对象,是否是改变了对象内部的值,还是改变了对象的引用。
2.不用除法,但是空间复杂度为2n.
//不用除法
class Solution {
public int[] productExceptSelf(int[] nums) {
if (nums == null || nums.length < 2) {
return nums;
}
long[] before = new long[nums.length];
long[] after = new long[nums.length];
before[0] = 1;
after[nums.length - 1] = 1;
long ascTemp = 1, descTemp = 1;
for (int i = 0; i < nums.length; ++i) {
ascTemp *= nums[i];
descTemp *= nums[nums.length - i - 1];
before[i] = ascTemp;
after[nums.length - i - 1] = descTemp;
}
int[] result = new int[nums.length];
for (int i = 0; i < nums.length; ++i) {
if(i==0){
result[i] = (int)after[i+1];
}else if(i==nums.length-1){
result[i] = (int)before[i-1];
}else{
result[i] = (int) (before[i-1] * after[i + 1]);
}
}
return result;
}
}
3.空间复杂度为常数的解决方案。
大佬的代码。链接深度机器学习--238. 除自身以外数组的乘积
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
vector<int> res(nums.size(),1);
if(nums.empty())
return res;
for(int i=1;i<nums.size();++i)
res[i] = res[i-1] * nums[i-1];
int right = 1;
for (int i = nums.size() - 1; i >= 0; --i) {
res[i] *= right;
right *= nums[i];
}
return res;
}
};
666