思路:求解除自身以外的所有数字的乘积,就是求解自身左侧的乘积与右侧乘积的乘积,可以分为两个子问题:自左向右求解累乘结果;自右向左求解累乘结果。已经计算的结果可以重复使用。代码如下:
public int[] productExceptSelf(int[] nums) {
if (nums == null || nums.length == 0) {
return nums;
}
int n=nums.length;
int[] leftRes=new int[n];
int[] rightRes=new int[n];
int[] answer=new int[n];
//求解左侧累乘结果与右侧累乘结果
leftRes[0]=nums[0];
rightRes[n-1]=nums[n-1];
for(int i=1;i<n;i++){
leftRes[i]=leftRes[i-1]*nums[i];
rightRes[n-1-i]=rightRes[n-i]*nums[n-1-i];
}
//求解最终结果
answer[0]=rightRes[1];
answer[n-1]=leftRes[n-2];
for(int i=1;i<n-1;i++){
answer[i]=leftRes[i-1]*rightRes[i+1];
}
return answer;
}
进阶:因为题目说明answer不在空间计算范围内,所以可以将一个辅助数组放到answer数组,另一个辅助数组使用单个累乘结果存放。代码如下:
public int[] productExceptSelf(int[] nums) {
if (nums == null || nums.length == 0) {
return nums;
}
int n=nums.length;
//answer存放自左向右累乘结果
int[] answer=new int[n];
answer[0]=1;
//rightRes存放自右向左累乘结果
int rightRes=1;
//自左向右计算answer
for(int i=1;i<n;i++){
answer[i]=answer[i-1]*nums[i-1];
}
//自右向左计算rightRes,并与answer对应项相乘
for(int i=n-1;i>=0;i--){
answer[i]=answer[i]*rightRes;
rightRes*=nums[i];
}
return answer;
}