package arrayandstring;publicclassProductExceptSelf{publicstaticvoidmain(String[] args){}//给定一个数组,就出除自身外的所有元素的乘积,要求:不能使用除法,且在 O(n) 时间复杂度内完成此题。//思路,如果可以使用除法,那么非常简单,只需要将数组的所有元素的乘积除以本身 就是 除自身外的所有元素的乘积//如果输入数组中出现 0,那么这个方法就失效了。而且在问题中说明了不允许使用除法运算。这增加了这个问题的难度。publicstaticint[]productExceptSelf(int[] num){if(num == null || num.length ==0){return num;//返回空}if(num.length ==1){
num[0]=0;return num;}int sum =1;for(int i =0; i < num.length; i ++){
sum *= num[i];}int[] res =newint[num.length];for(int i =0; i < num.length; i ++){
res[i]= sum / num[i];}return res;}//如果限制了不可以使用除法,且在 O(n) 时间复杂度内完成此题。//思路2:前缀和后缀,不必将所有数字的乘积除以给定索引处的数字得到相应的答案,//而是利用索引左侧所有数字的乘积和右侧所有数字的乘积(即前缀与后缀)相乘得到答案。//对于给定索引 i,我们将使用它左边所有数字的乘积乘以右边所有数字的乘积。publicstaticint[]productExceptSelf02(int[] num){if(num == null || num.length ==0){return num;//返回空}if(num.length ==1){
num[0]=0;return num;}int len = num.length;int[] L =newint[len];int[] R =newint[len];int[] res =newint[len];//填充前缀乘积,不包括i
L[0]=1;for(int i =1; i < len; i ++){
L[i]= L[i -1]* num[i -1];}
R[len -1]=1;for(int i = len -2; i >=0; i --){
R[i]= R[i +1]* num[i +1];}//前缀乘后缀for(int i =0; i < len; i ++){
res[i]= L[i]* R[i];}return res;}//思路3:通过思路2,可以发现,其实可以只够造前缀,而后缀只需要一个变量表示即可publicint[]productExceptSelf03(int[] nums){int length = nums.length;int[] answer =newint[length];// answer[i] 表示索引 i 左侧所有元素的乘积// 因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1
answer[0]=1;for(int i =1; i < length; i++){
answer[i]= nums[i -1]* answer[i -1];}// R 为右侧所有元素的乘积// 刚开始右边没有元素,所以 R = 1int R =1;for(int i = length -1; i >=0; i--){// 对于索引 i,左边的乘积为 answer[i],右边的乘积为 R
answer[i]= answer[i]* R;// R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上
R *= nums[i];}return answer;}}