除自身以外陣列的乘積

2021-09-09 06:31:12 字數 1857 閱讀 9066

目錄

1 題目描述

2 題目分析

3 **實現

給定長度為 n 的整數陣列nums,其中 n > 1,返回輸出陣列output,其中output[i]等於nums中除nums[i]之外其餘各元素的乘積。

示例:

輸入:[1,2,3,4]輸出:[24,12,8,6]
說明:不要使用除法,且在 o(n) 時間複雜度內完成此題。

高階:

你可以在常數空間複雜度內完成這個題目嗎?( 出於對空間複雜度分析的目的,輸出陣列不被視為額外空間。)

如果沒有題目中的限制,那麼res[i]=a[0]*a[1]*...*a[n]/a[i]就能很容易的求出答案了,但是這裡明確要求時間複雜度為o(n),空間複雜度為o(1),那該怎麼做呢?

實際上,對於每乙個數,除其自身以外陣列的乘積等於左邊所有數的乘積*右邊所有數的乘積,用seq[i]表示nums[i]左邊所有數的乘積,rev[i]表示nums[i]右邊所有數的乘積,那麼很顯然res[i]=sea[i]*rev[i],這個過程用圖來描述如下:

如圖所示,seq陣列為順序乘積,rev陣列為逆序乘積,而對於seq陣列和rev陣列,遍歷一次nums陣列即可將二者全部賦值,再遍歷一次即可將res得出來,不過這樣時間複雜度為o(2n)近似為o(n),但是很明顯空間複雜度也近似為o(n)了,與題意不符,那麼該怎麼改進呢?

實際上,我們可以發現,seq陣列和rev陣列的元素都是迭代前面或後面累積乘積計算的,因此可以考慮用變數來替換掉兩個陣列。

定義變數seqmul和revmul分別表示順序累積乘積和逆序累積乘積,分別從0和len-1開始累積。在遍歷nums陣列到nums[i]時,seqmul也從0到i-1累積相乘得到了nums[i]左邊所有數的乘積,因此可以先將seqmul儲存在res[i]中;而另一方面,revmul也從len-1到len-2+i累計相乘得到了nums[len-1-i]右邊所有數的乘積,因此先將revmul儲存在res[len-1-i]中。然後繼續遍歷,

當遍歷到nums[len-1-i]時,seqmul也從0到len-2-i累積相乘得到了nums[len-1-i]左邊所有數的乘積,而此時res[len-1-i]中儲存著前面遍歷得到的nums[len-1-i]右邊所有數的乘積,此時再將res[len-1-i]*seqmul,得到的便是nums[len-1-i]左右兩邊所有數的乘積,也就是最終所要求的;而另一方面的revmul也從len-1到i+1累計相乘得到了nums[i]右邊所有數的乘積,而此時res[li]中儲存著前面遍歷得到的nums[i]左邊所有數的乘積,此時再將res[i]*revmul,得到的便是nums[i]左右兩邊所有數的乘積,也就是最終所要求的.....

通過這樣的方法,就可以只在一次遍歷後得到結果,時間複雜度為o(n),空間複雜度只是定義了幾個變數,因此為o(1)。

**實現如下:

vectorproductexceptself(vector& nums)  

return res;

}

除自身以外陣列的乘積

給定長度為 n 的整數陣列nums,其中 n 1,返回輸出陣列output,其中output i 等於nums中除nums i 之外其餘各元素的乘積。示例 輸入 1,2,3,4 輸出 24,12,8,6 說明 請不要使用除法,且在 o n 時間複雜度內完成此題。高階 你可以在常數空間複雜度內完成這個...

除自身以外陣列的乘積

提交 總結給你乙個長度為 n 的整數陣列 nums,其中 n 1,返回輸出陣列 output 其中 output i 等於 nums 中除 nums i 之外其餘各元素的乘積。示例 輸入 1,2,3,4 輸出 24,12,8,6 說明 請不要使用除法,且在 o n 時間複雜度內完成此題。高階 你可以...

除自身以外陣列的乘積

leetcode 238 左右列表 public int productexceptself int nums for int i nums.length 2 i 0 i for int i 0 i return res 空間為o 1 由於輸出陣列不算在空間複雜度內,那麼我們可以將 l 或 r 陣列...