本文最后更新于78 天前,其中的信息可能已经过时,如有错误请发送邮件到3091169959@qq.com
一、题目描述
给你一个整数数组 nums
,返回 数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积 。
题目数据 保证 数组 nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(n)
时间复杂度内完成此题。
示例 1:
输入: nums =[1,2,3,4]
输出:[24,12,8,6]
示例 2:
输入: nums = [-1,1,0,-3,3] 输出: [0,0,9,0,0]
提示:
2 <= nums.length <= 105
-30 <= nums[i] <= 30
- 输入 保证 数组
answer[i]
在 32 位 整数范围内
进阶:你可以在 O(1)
的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组 不被视为 额外空间。)
二、题目分析
如果没有限制条件,这道题大家应该都会写,但是题目加上了不能使用除法,时间复杂度为 O(n),空间复杂度为 O(1),所以我们不能先计算整个数组的乘积,然后除以每个元素来得到结果,除了输出数组外,不能使用额外的空间。所以我们只要经过两次遍历,第一次遍历数组,计算每个位置的前缀积,并直接存储在 ans中;第二次遍历数组,计算每个位置的后缀积,并将其与 ans中的前缀积相乘,得到最终结果。
三、代码实现
public static class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] ans = new int[n];
Arrays.fill(ans,1);
int left = 0,right = n-1;
int lp = 1 , rp = 1;
while(left < n && right >=0) {
ans[right] *= rp;
ans[left] *= lp;
lp *= nums[left++];
rp *= nums[right--];
}
return ans;
}
}
提交结果:
看来使用双指针只是代码看着简单点,实际上还是需要性能,所以这一次我把双指针拆开到两次遍历中,
与此同时也是牺牲了一部分空间的性能。
四、总结
最近做的都是数组的题目,不过今天周一,争取这周把数组刷完进入下一篇章!