力扣-238-除自身以外数组的乘积

要求时间复杂度O(N),也就是说一次遍历,然后不让用除法
也就是说不能拿总乘积挨个除
不能双重for循环
但是没限制空间复杂度
能不能比如一个数组
pre[i]表示截至截至i(包括)前i个元素的乘积和
next[i]表示从i开始到结尾的元素的乘积和
第三次遍历就可以利用上面的结果算出来了

这里的两个辅助数组必须有额外的一个长度,来保存边界情况

大概这个样子

vector<int> productExceptSelf(vector<int>& nums) {
	int n = nums.size();
	vector<int> res,pre(n+1),next(n+1);

	pre[0] = 1, next[n] =1;

	for (int i = 1; i <= n; i++) 
		pre[i] = nums[i-1] * pre[i - 1];	

	for (int i = n - 1; i >= 0; i--)
		next[i] = nums[i] * next[i + 1];

	for (int i = 0; i < n; i++)
		res.push_back(pre[i] * next[i+1]);

	return res;
}

这里直接用push_back()避免res数组长度和另外两个辅助数组不一致造成的麻烦
就是没想到空间效率这么差,用的数组多了,而且可能没必要写三个循环

vector<int> productExceptSelf(vector<int>& nums) {
	int n = nums.size();
	vector<int> res,next(n+1);

	int pre = 1;
	next[n] =1;

	for (int i = n - 1; i >= 0; i--)
		next[i] = nums[i] * next[i + 1];

	for (int i = 1; i <= n; i++) {
		res.push_back(pre * next[i]);
		pre = nums[i - 1] * pre;
	}

	return res;
}

优化了一个数组和一个循环,但是空间效率仍然不高,我觉得除非换思路不然没法优化了

官方题解的进一步空间优化是,直接把next数组和res数组合并,操作next数组并返回作为结果数组
这就是最终的代码了

vector<int> productExceptSelf(vector<int>& nums) {
	int n = nums.size();
	vector<int> next(n);

	int pre = 1;
	next[n-1] =1;

	for (int i = n - 2; i >= 0; i--)
		next[i] = nums[i+1] * next[i + 1];

	for (int i = 1; i <= n; i++) {
		next[i - 1] = pre * next[i - 1];
		pre = nums[i - 1] * pre;
	}

	return next;
}
posted @ 2022-11-04 16:11  YaosGHC  阅读(28)  评论(0)    收藏  举报