Leecode238 除以自身因以外的数组

题目描述:

/*
* 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
 
题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在  32 位 整数范围内。
 
请不要使用除法,且在 O(n) 时间复杂度内完成此题。
 
输入: nums = [1,2,3,4]
输出: [24,12,8,6]
 
输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]
 
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/product-of-array-except-self
*/

思路:

时间要求为O(n),且不能用除法——空间换时间?遍历过程保存遍历过的数的乘积?

解决方案:

维护乘积数组:维护两个数组L、R,L[i]与R[i]表示数组i除自己外左边乘积或右边乘积。对于头尾元素,L[0]与R[nums.size() - 1]设置为1. L[i] = L[i - 1]与nums[i]的乘积(因为L[i - 1]表示nums[i]左边所有元素的乘积,不包括nums[i])。R[i]同理。

#include<iostream>
#include<vector>
using namespace std;
vector<int> productExceptSelf(vector<int>& nums)
{
	//左右数组乘机:维护两个数组L、R,L[i]与R[i]表示除自己nums[i]外左边所有数乘积或右边所有数    
    //乘积
	vector<int> L(nums.size(), 0);
	vector<int> R(nums.size(), 0);

	L[0] = 1;
	for (int i = 1; i < nums.size(); i++)
	{
		L[i] = L[i - 1] * nums[i - 1];
	}

	R[nums.size() - 1] = 1;
	for (int i = nums.size() - 2; i >= 0; i--)
	{
		R[i] = R[i + 1] * nums[i];
	}

	for (int i = 0; i < nums.size(); i++)
	{
		L[i] *= R[i];
	}
	return L;
}

时间复杂度为O(n),空间复杂度为O(n).

能否优化?

只需要L数组,对于R数组动态构造,构造过程:

        L数组构造完成后,由于没有R数组,从前向后遍历无法得出答案,考虑从后向前

        i = nums.size() - 1时,R = 1,L[i] = L[i] * R,更新完L[i]后,更新R,R = R * nums[i]

        迭代直至结束。

#include<iostream>
#include<vector>
using namespace std;
vector<int> productExceptSelf(vector<int>& nums)
{
	//维护两个数组L,L[i]数组i除自己外左边乘积
	vector<int> L(nums.size(), 0);

	//优化:空间复杂度优化为O(1) 只使用L数组,对R数组动态构建
	for (int i = 1; i < nums.size(); i++)
	{
		L[i] = L[i - 1] * nums[i - 1];
	}

	int R = 1;
	for (int i = nums.size() - 1; i >= 0; i--)
	{
		L[i] = L[i] * R;
		R *= nums[i];
	}
	return L;
}

         

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值