1.左右乘积列表
这个题目当然也是剑指offer里的题目,方法就是构造一个左乘积数组left,构造一个右乘积数组right,然后对于每一个i,它的结果就应该是left[i-1] * right[i+1]
。思想比较好理解直接上代码:
public int[] productExceptSelf(int[] nums) {
if(nums.length < 2)
return nums;
int nLength = nums.length;
int[] left = new int[nLength];left[0] = nums[0];
int[] right = new int[nLength]; right[nLength-1] = nums[nLength-1];
for (int i = 1, j = nLength-2; i < nLength && j >= 0; ++i, --j) {
left[i] = left[i-1] * nums[i];
right[j] = right[j+1] * nums[j];
}
int[] result = new int[nLength];
for (int i = 1; i < nLength-1; ++i) {
result[i] = left[i-1] * right[i+1];
}
result[0] = right[1];
result[nLength-1] = left[nLength-2];
return result;
}
2.动态构建右(左)数组
上面我们构建了两个辅助数组,然后最后得到一个结果数组。那如果不使用额外的空间呢,也好办。我们就先让结果数组是左数组,然后动态的去找相应的right
值并与左数组的元素想乘得到结果。代码如下:
public int[] productExceptSelf(int[] nums) {
if(nums.length < 2)
return nums;
int nLength = nums.length;
int[] result = new int[nLength];result[0] = nums[0];
for (int i = 1; i < nLength; ++i) {
result[i] = result[i-1] * nums[i]; //先将result构建为left
}
int right = 1; //right初始为1
for (int i = nLength-1; i > 0; --i) {
result[i] = right * result[i-1]; //每次往左走,都更新result和right
right *= nums[i];
}
result[0] = right; //最后的这个result就是0,相当于-1的位置的left也为1,和right初始为1对应
return result;
}