4.19除自身以外数组的乘积
我自己的思路,想用双指针, 一个从左边left开始乘,一个从右边right开始乘,如果left,或者right遇到了目标索引i(也就是我们要跨过去的当前元素),那么直接让对应的指针加一,当前元素不参与累积的计算,直到俩指针相遇。但是有个小细节问题就是如果,数组是奇数个元素,那么最中间的元素在while循环中是乘不到任何一个指针里的,所以得另外处理最中间元素,总体代码如下:
class Solution {public int[] productExceptSelf(int[] nums) {if(nums.length<=1) return new int[0];int left=0,right = nums.length-1;int productl = 1,productr = 1;int[] ans = new int [nums.length];int point = 1;for (int i = 0; i < nums.length; i++) {while (left < right) {if (left == i) {left++;} else {productl = productl * nums[left];left++;}if (right == i) {right--;} else {productr = productr * nums[right];right--;}}if(nums.length % 2 ==1){if(i == Math.floor(nums.length/2)){point = 1;}else point = nums[left];}ans[i] = productl*productr*point;productl = 1;productr = 1;left=0;right = nums.length-1;}return ans;}
}
复杂度是o(N2)所以超时了,看了一下官方的解法,用的前缀表思想。我一开始也想到前缀表,但是我想的是只用一个前缀表从左向右乘,但是题目不让用除法,所以感觉这种思路不如双指针简单。但是官方解法是定义一个前缀表,定义一个后缀表,然后分别记录该索引i左侧所有数字的乘积和右侧所有数字的乘积。最后结果就是i对应位置前缀表后缀表相乘。
class Solution {public int[] productExceptSelf(int[] nums) {int [] left = new int[nums.length];int [] right = new int[nums.length];int [] ans = new int[nums.length];left[0] = 1;for(int i = 1; i < nums.length; i++) {left[i] = left[i-1] * nums[i-1];}right[nums.length-1] = 1;for(int i = nums.length-2; i >= 0; i--) {right[i] = right[i+1] * nums[i+1];}for(int i = 0; i < nums.length; i++) {ans[i] = left[i] * right[i];}return ans;}
}
以上来自于力扣解题