输入一个数组,返回一个数组,
返回的数组中A[i] 表示原数组中除了第i个以外的所有元素的乘积
例:
输入:{1,2,3,4}
输出:{24,12,8,6}
老规矩,上来先来个n平方算法
public static int[] ArrayExceptSelfNN(int[] input)
{
if (input == null)
{
Console.WriteLine("null");
return null;
}
int length = input.Length;
var output = new int[length];
for (int i = 0; i < length; i++)
{
output[i] = 1;
for (int j = 0; j < input.Length; j++)
{
if (i!=j)
{
output[i] *= input[j];
}
}
}
return output;
}
接下来分析一下出题人的意图:
他想让我死···
看了一下网上的写法,大家都是用左边乘以右边,我们也来学习一下。
public static int[] ArrayExceptSelf2N(int[] input)
{
if (input == null)
{
Console.WriteLine("null");
return null;
}
int length = input.Length;
var left = new int[length];
var right = new int[length];
var output = new int[length];
left[0] = 1;
right[length - 1] = 1;
//先算出左边的
for (int i = 1; i < length; i++)
{
left[i] = left[i - 1] * input[i - 1];
}
//倒数第二个开始,最后一个是length - 1,
for (int i = length - 2; i >= 0; i--)
{
right[i] = right[i + 1] * input[i + 1];
}
for (int i = 0; i < length; i++)
{
output[i] = left[i] * right[i];
}
return output;
}
但是这样虽然时间复杂度降下来了,但是空间复杂度却很高,开了3倍的输入数组长度来运行,这是很不划算的,我们可以把中间变量省略掉来节约空间。
public static int[] ArrayExceptSelfN(int[] input)
{
if (input == null)
{
Console.WriteLine("null");
return null;
}
int length = input.Length;
var output = new int[length];
var right = 1;
output[0] = 1;
for (int i = 1; i < length; i++)
{
output[i] = output[i - 1] * input[i - 1];
}
for (int i = length - 2; i >= 0; i--)
{
right *= input[i + 1];
output[i] *= right;
}
return output;
}