劍指offer 66. 構建乘積數組數組
題目:spa
給定一個數組A[0, 1, ..., n-1],請構建一個數組B[0, 1, ..., n-1],其中B中的元素B[i] = A[0] * A[1] * ... * A[i-1] * A[i +1] ... A[n-1]。不能使用除法。code
同leetcode 238blog
https://leetcode.com/problems/product-of-array-except-self/ip
分析:leetcode
假如能夠利用除法,則利用(A[0]*A[1]*...A[n-1])/A[i],但必定要注意A[i]等於 0 的狀況!!!get
暴力解決須要使用O(n^2)來構建數組B,不夠高效。for循環
使用O(n)的時間複雜度來解決本題:class
思路比較巧妙,咱們知道B[i] = A[0] * A[1] * ... * A[i-1] * A[i+1] ... A[n-1],因此咱們將B[i]獲得的過程分爲兩部分:循環
第一部分:A[0] * A[1] * ... * A[i-1];第二部分: A[i+1] * ... * A[n-1]
咱們先「自底向上」計算第一部分,並存儲到B中;而後「自頂向下」計算第二部分,並結合B中的第一部分,「自頂向下」更新B中元素。
兩個順序的for循環解決問題。
void multiply(const vector<double>& array1, vector<double>& array2) { int length1 = array1.size(); int length2 = array2.size(); if (length1 == length2 && length2 > 1) { array2[0] = 1; // 計算並存儲第一部分 for (int i = 1; i < length1; ++i) { array2[i] = array2[i - 1] * array1[i - 1]; } // 計算第二部分並更新array2 double temp = 1; for (int i = length1 - 2; i >= 0; --i) { // 此時array2[length2 -1]已爲正確值 temp *= array1[i + 1]; array2[i] *= temp; } } }
總結:
本解決方法時間複雜度爲O(n)。
本題解決思路巧妙,也是對於問題觀察得來的結果。也許想到分紅兩部分來講不難,尤爲是作過一遍以後,可是兩個for循環的寫法很是值得借鑑,也是對整個清晰思路的完美反映。