Saya ditanya pertanyaan ini dalam wawancara kerja, dan saya ingin tahu bagaimana orang lain akan menyelesaikannya. Saya paling nyaman dengan Java, tetapi solusi dalam bahasa lain dipersilahkan.
Diberikan array angka,,
nums
kembalikan array angkaproducts
, di manaproducts[i]
produk dari semuanums[j], j != i
.Input : [1, 2, 3, 4, 5] Output: [(2*3*4*5), (1*3*4*5), (1*2*4*5), (1*2*3*5), (1*2*3*4)] = [120, 60, 40, 30, 24]
Anda harus melakukan ini
O(N)
tanpa menggunakan divisi.
[interview-questions]
tag mencarinya. Apakah Anda memiliki tautan jika Anda menemukannya?Jawaban:
Penjelasan metode polygenelubricants adalah: Caranya adalah dengan membangun array (dalam kasus untuk 4 elemen)
Keduanya dapat dilakukan di O (n) dengan mulai masing-masing di tepi kiri dan kanan.
Kemudian mengalikan dua elemen array dengan elemen memberikan hasil yang diperlukan
Kode saya akan terlihat seperti ini:
Jika Anda perlu menjadi O (1) di ruang angkasa juga Anda dapat melakukan ini (yang IMHO kurang jelas)
sumber
v_i=0
maka satu-satunya entri non nol dalam hasilnya adalah elemen engan. Namun saya menduga bahwa menambahkan pass untuk mendeteksi dan menghitung elemen nol akan mengurangi kejelasan solusi, dan mungkin tidak membuat keuntungan kinerja nyata dalam sebagian besar kasus ..Berikut adalah fungsi rekursif kecil (dalam C ++) untuk melakukan modofikasi di tempat. Ini membutuhkan O (n) ruang ekstra (on stack). Dengan asumsi array dalam a dan N memiliki panjang array, kita miliki
sumber
num[N-1]
; kemudian dalam perjalanan kembali itu menghitung bagian kedua dari perkalian yang kemudian digunakan untuk mengubah array angka di tempatnya.Inilah upaya saya untuk menyelesaikannya di Jawa. Permintaan maaf untuk pemformatan non-standar, tetapi kode memiliki banyak duplikasi, dan ini adalah yang terbaik yang bisa saya lakukan untuk membuatnya dapat dibaca.
Invarian loop adalah
pi = nums[0] * nums[1] *.. nums[i-1]
danpj = nums[N-1] * nums[N-2] *.. nums[j+1]
. Bagiani
di sebelah kiri adalah logika "awalan", danj
bagian di sebelah kanan adalah logika "akhiran".Satu liner rekursif
Jasmeet memberikan solusi rekursif (indah!); Saya telah mengubahnya menjadi ini (mengerikan!) Java one-liner. Itu modifikasi di tempat , dengan
O(N)
ruang sementara di stack.sumber
Menerjemahkan solusi Michael Anderson ke dalam Haskell:
sumber
Secara diam-diam menghindari aturan "tidak ada pembagian":
sumber
Ini dia, solusi sederhana dan bersih dengan kompleksitas O (N):
sumber
C ++, O (n):
sumber
Di)
sumber
Inilah solusi saya di C ++ modern. Itu memanfaatkan
std::transform
dan cukup mudah diingat.Kode online (kotak suara).
sumber
Ini O (n ^ 2) tetapi f # sangat indah:
sumber
Hitung ulang produk angka di sebelah kiri dan di sebelah kanan setiap elemen. Untuk setiap elemen, nilai yang diinginkan adalah produk dari produk tetangga.
Hasil:
(PEMBARUAN: sekarang saya melihat lebih dekat, ini menggunakan metode yang sama seperti Michael Anderson, Daniel Migowski dan polygenelubricants di atas)
sumber
Rumit:
Gunakan yang berikut ini:
Ya, saya yakin saya melewatkan beberapa i-1, bukan saya, tapi itulah cara untuk menyelesaikannya.
sumber
Ada juga solusi tidak optimal O (N ^ (3/2)) . Ini cukup menarik.
Pertama preprocess setiap perkalian parsial ukuran N ^ 0,5 (ini dilakukan dalam kompleksitas waktu O (N)). Kemudian, perhitungan untuk kelipatan nilai-nilai lain-setiap angka dapat dilakukan dalam waktu 2 * O (N ^ 0,5) (mengapa? Karena Anda hanya perlu melipatgandakan elemen terakhir dari nomor lainnya ((N ^ 0,5) - 1), dan kalikan hasilnya dengan ((N ^ 0,5) - 1) angka yang termasuk dalam kelompok nomor saat ini). Melakukan ini untuk setiap nomor, satu bisa mendapatkan O (N ^ (3/2)) waktu.
Contoh:
4 6 7 2 3 1 9 5 8
hasil parsial: 4 * 6 * 7 = 168 2 * 3 * 1 = 6 9 * 5 * 8 = 360
Untuk menghitung nilai 3, kita perlu melipatgandakan nilai kelompok lain 168 * 360, dan kemudian dengan 2 * 1.
sumber
Solusi ini saya buat dan saya merasa sangat jelas apa yang Anda pikirkan !?
sumber
arr = [1, 2, 3, 4, 5] prod = [] menghasilkan (arr, prod, 0) mencetak prod
sumber
Untuk menjadi lengkap di sini adalah kode dalam Scala:
Ini akan mencetak yang berikut ini:
Program akan menyaring elem saat ini (_! = Elem); dan gandakan daftar baru dengan metode reduceLeft. Saya pikir ini akan menjadi O (n) jika Anda menggunakan tampilan scala atau Iterator untuk eval malas.
sumber
Berdasarkan jawaban Billz - maaf saya tidak bisa berkomentar, tapi di sini ada versi scala yang menangani item duplikat dengan benar, dan mungkin O (n):
pengembalian:
sumber
Menambahkan solusi javascript saya di sini karena saya tidak menemukan orang menyarankan ini. Apa yang harus dibagi, kecuali untuk menghitung berapa kali Anda dapat mengekstraksi angka dari nomor lain? Saya menghitung produk seluruh array, dan kemudian beralih ke setiap elemen, dan mengurangi elemen saat ini sampai nol:
sumber
Saya gunakan untuk C #:
sumber
Kita dapat mengecualikan
nums[j]
(di manaj != i
) dari daftar terlebih dahulu, lalu mendapatkan produk sisanya; Berikut ini adalahpython way
untuk menyelesaikan puzzle ini:sumber
Nah, solusi ini dapat dianggap sebagai C / C ++. Katakanlah kita memiliki array "a" yang mengandung n elemen seperti [n], maka kode pseudo akan seperti di bawah ini.
sumber
Satu lagi solusi, Menggunakan pembagian. dengan dua kali traversal. Lipat gandakan semua elemen dan kemudian mulai membaginya dengan setiap elemen.
sumber
sumber
Ini kode saya:
sumber
Berikut ini contoh yang sedikit fungsional, menggunakan C #:
Saya tidak sepenuhnya yakin bahwa ini adalah O (n), karena semi-rekursi dari Funcs yang dibuat, tetapi tes saya tampaknya menunjukkan bahwa itu O (n) pada waktunya.
sumber
// Ini adalah solusi rekursif di Jawa // Disebut sebagai berikut dari produk utama (a, 1,0);
sumber
Solusi yang rapi dengan runtime O (n):
Buat array akhir "hasil", untuk elemen i,
sumber
sumber
Berikut ini adalah konsep sederhana lain yang memecahkan masalah di
O(N)
.sumber
Saya punya solusi dengan kompleksitas
O(n)
ruang danO(n^2)
waktu yang disediakan di bawah ini,sumber