長さ n (n > 1) の整数配列 nums を指定すると、出力配列 Output が返されます。ここで、output[i] は、nums[i] を除く nums の残りの要素の積に等しくなります。
例:
入力: [1,2,3,4]
出力: [24,12,8,6]
ヒント: 質問データは、質問データのすべての要素のすべてのプレフィックス要素を保証します。 array サフィックス (または配列全体) の積は、32 ビット整数の範囲内にあります。
指示: 除算を使用せず、この問題を O(n) 時間以内に完了してください。
上級: 一定の空間複雑さ内でこの問題を完了できますか? (空間複雑性分析の目的では、出力配列は余分な空間とはみなされません。)
解決策質問を受けたときの最初のアイデアは、for ループが 2 つ、積が 1 つ、除算が 1 つということでした。しかし、後で分かったのですが、説明書には割り算を使用しないようにと書かれていたため、他の方法を使用する必要がありました。 自分以外の累積乗算を計算しているので、現在位置を分割点として、左側の要素の積と右側の要素の積をそれぞれ計算して乗算することができます。 これには次の解決策があります:L[i] = L[i-1] * nums[i-1]。
同様に、配列R の場合、R[length-1] は 1 である必要があります。長さは入力配列のサイズを指します。その他の要素: R[i] = R[i+1] * nums[i+1]。
R 配列と L 配列が満たされたら、入力配列を反復処理するだけでよく、インデックス i の値は次のようになります:L[i] * R[i]。
class Solution { public int[] productExceptSelf(int[] nums) { int arrLen = nums.length; int[] leftNums = new int[arrLen]; int[] rightNums = new int[arrLen]; leftNums[0] = 1;rightNums[arrLen-1] = 1; for(int i = 1; i < arrLen; i++){ leftNums[i] = leftNums[i-1] * nums[i-1]; rightNums[arrLen-i-1] = rightNums[arrLen-i] * nums[arrLen-i]; } for(int i = 0; i < arrLen; i++){ leftNums[i] *= rightNums[i]; } return leftNums; } }
複雑度分析
時間計算量: O(N)、ここで、N は配列 nums のサイズを指します。 L 配列と R 配列の前処理と最終的な走査計算はどちらも O(N) 時間の複雑さです。
空間複雑度: O(N)、N は配列 nums のサイズを指します。 L 配列と R 配列は、答えを作成するために使用されます。L 配列と R 配列の長さは、配列 nums のサイズです。
アルゴリズム 2: 共有配列法 全体的なアイデアは、公式の問題解決アイデアと同じです:左の乗算 * 右の乗算。
戻り配列returnNums を定義し、左端と右端からデータを埋めながら共有配列として扱います。次に、左端と右端の積を格納し、ループで更新する left,right を定義します。
left*right です。
returnNums[i] = 左 および returnNums[j] = 右。
class Solution { public int[] productExceptSelf(int[] nums) { int arrLen = nums.length; int[] returnNums = new int[arrLen]; int left = 1, right = 1; // 临时存储 returnNums[0] = 1; returnNums[arrLen-1] = 1; for(int i = 1, j = arrLen-2; i < arrLen; i++, j--){ left *= nums[i-1]; right *= nums[j+1]; if(i < j){ // 两指针为交会 returnNums[i] = left; returnNums[j] = right; }else if(i == j){ // 两指针重合,奇数位情况下发生 returnNums[i] = left*right; }else{ // 两指针错位 returnNums[i] *= left; returnNums[j] *= right; } } return returnNums; } }
複雑度分析
時間計算量: O(N)、前の問題解決方法と同じ、長さNのループが実行され、その時間計算量はO( N )。
スペースの複雑さ: O(1)。タイトルで述べたように、返された配列のスペースはカウントされないため、使用される追加のストレージスペースは左右になります。したがって、一定レベルの空間複雑性のみが存在します。
以上が[LeetCode]238. 自分以外の配列の積を解くためのアイデアの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。