タイトル
【数组的乘积(除了自身)】
、アレーのNUMS nは整数ここで、n> 1の所与のアレイ出力を返すように出力[I] [i]はNUMS除くNUMSのすべての要素の積に等しいです。
例:
Input: [1,2,3,4]
Output: [24,12,8,6]
注:区分なしとO(n)の中でそれを解決してください。
フォローアップ:
あなたは、一定のスペースの複雑さと、それを解決してもらえますか?(出力配列は、スペースの複雑性分析の目的のために余分なスペースとしてカウントされません。)
思考
キーは、この位置は2つの部分、左半分と右半分の産物であってもよい、分周器ではありません。
の積[]の左半分に対応する記録位置の下に左から右へと通じ初めて、私たちは、新しい配列を持っています。
右から2番目のパス、スーツは、[製品]の右半分に対応する記録位置のままです。
最後に、アレイに対応する2つの位置が結果アレイを得るために、乗算しました。
時間複雑:O(n)の
空間の複雑さ:O(1)
コード
class Solution {
public int[] productExceptSelf(int[] nums) {
int[] res = new int[nums.length];
int[] left = new int[nums.length];
int[] right = new int[nums.length];
// 对应位置左半部分的乘积
left[0] = 1;
for (int i =1;i < left.length ;i++ ) {
left[i] = left[i-1] * nums[i-1];
}
// 对应位置右半部分的乘积
right[right.length-1] = 1;
for(int i = right.length-2; i >= 0; i--){
right[i] = right[i+1]*nums[i+1];
}
for(int i =0;i<res.length;i++){
res[i]=left[i]*right[i];
}
return res;
}
}
結果を発表
改善します
上記の方法は3つの新しいアレイを開いた、我々はそれを合理化することができ、あなただけの1つの結果の配列を使用することができます。
左あなたは解像度で保存することができ、製品の一部、および右から左の更新処理では、この変数の右半分に製品を保持するために「右」のプロセス変数に左にのみトラバースする必要があります。
コード
class Solution {
public int[] productExceptSelf(int[] nums) {
int[] res = new int[nums.length];
res[0] = 1;
for (int i =1;i < res.length ;i++ ) {//最左端位置,最后结果中没有左半部分乘积
res[i] = res[i-1] * nums[i-1];//此时的res[i]记录的为该位置的左半部分的乘积
}
int right = 1;//右半部分的乘积,因为最右端的位置,最后结果的构成中:没有右半部分乘积,只有左半部分,所以right从1开始
for(int i = res.length-1; i >= 0; i--){
res[i] *= right;//每个位置需要乘上对应的右半部分的乘积
right *= nums[i];//right进行累乘,作为下一个位置的右半部分乘积
}
return res;
}
}