Diberikan array n bilangan bulat dan diberi nomor X, temukan semua pasangan unik elemen (a, b), yang penjumlahannya sama dengan X.
Berikut ini adalah solusi saya, itu adalah O (nLog (n) + n), tetapi saya tidak yakin apakah sudah optimal atau tidak.
int main(void)
{
int arr [10] = {1,2,3,4,5,6,7,8,9,0};
findpair(arr, 10, 7);
}
void findpair(int arr[], int len, int sum)
{
std::sort(arr, arr+len);
int i = 0;
int j = len -1;
while( i < j){
while((arr[i] + arr[j]) <= sum && i < j)
{
if((arr[i] + arr[j]) == sum)
cout << "(" << arr[i] << "," << arr[j] << ")" << endl;
i++;
}
j--;
while((arr[i] + arr[j]) >= sum && i < j)
{
if((arr[i] + arr[j]) == sum)
cout << "(" << arr[i] << "," << arr[j] << ")" << endl;
j--;
}
}
}
while((arr[i] + arr[j]) <= sum && i < j)
seharusnyawhile( i < J && arr[i] + arr[j] <= sum )
. (serupa untuk subloop kedua)Jawaban:
sumber
arr=[1,2,1,2,1,2,1,...]
. Untuk keunikan berdasarkan nilai, sepertinya tabel hash lain yang dikunci oleh pasangan nilai akan berhasil. Masih merupakan jawaban yang bagus, ringkas, dan elegan. +1hash(K - arr[i]) != i
entah bagaimana memeriksa kehadiran dan kurangnya kecocokan? Saya berharap akan ada pemeriksaan terpisah untuk kehadiran.Ada 3 pendekatan untuk solusi ini:
Misalkan jumlahnya T dan n adalah ukuran array
Pendekatan 1:
Cara naif untuk melakukan ini adalah dengan memeriksa semua kombinasi (n pilih 2). Pencarian lengkap ini adalah O (n 2 ).
Pendekatan 2:
Cara yang lebih baik adalah dengan mengurutkan array. Ini membutuhkan O (n log n)
Kemudian untuk setiap x dalam larik A, gunakan pencarian biner untuk mencari Tx. Ini akan membutuhkan O (nlogn).
Jadi, pencarian keseluruhan adalah O (n log n)
Pendekatan 3:
Cara terbaik adalah memasukkan setiap elemen ke dalam tabel hash (tanpa penyortiran). Ini mengambil O (n) sebagai penyisipan waktu konstan.
Kemudian untuk setiap x kita tinggal mencari komplemennya, Tx, yaitu O (1).
Secara keseluruhan run time dari pendekatan ini adalah O (n).
Anda dapat merujuk lebih lanjut di sini . Terima kasih.
sumber
Implementasi di Java: Menggunakan algoritma codaddict (Mungkin sedikit berbeda)
Untuk input =
{2,45,7,3,5,1,8,9}
dan jika Sum10
Pasangan keluaran:
Beberapa catatan tentang solusinya:
sumber
put(k-input[i], input[i])
(codaddicts menempatkan indeks sebagai nilai yang berguna.) Apa yang Anda tulis dapat disederhanakan menjadifor (i:input){ if (intSet.contains(sum-i) { print(i + "," + (sum-i) ); } else {intSet.add(i)}
Solusi di java. Anda dapat menambahkan semua elemen String ke ArrayList string dan mengembalikan daftar tersebut. Di sini saya hanya mencetaknya.
sumber
Implementasi Python:
Keluaran:
sumber
C ++ 11, kompleksitas run time O (n):
sumber
Berikut ini penyihir solusi yang memperhitungkan entri duplikat. Itu ditulis dalam javascript dan mengasumsikan array diurutkan. Solusi berjalan dalam waktu O (n) dan tidak menggunakan memori tambahan selain variabel.
Saya memecahkan ini selama wawancara untuk sebuah perusahaan besar. Mereka mengambilnya tapi bukan aku. Jadi ini dia untuk semua orang.
Mulailah di kedua sisi larik dan perlahan-lahan lanjutkan ke dalam untuk memastikan untuk menghitung duplikat jika ada.
Ini hanya menghitung pasangan tetapi dapat dikerjakan ulang menjadi
Nikmati!
sumber
if(distI > distK) while(_arr[++i]==curI); else while(_arr[--k]==curK);
Di)
Metodologi: a + b = c, jadi daripada mencari (a, b) kita mencari a = c - b
sumber
Implementasi di Java: Menggunakan algoritma codaddict:
Keluaran:
Jika Anda ingin pasangan duplikat (misalnya: 80,80) juga maka hapus saja && (Integer) mapping.get (ka [i])! = I dari kondisi if dan Anda siap melakukannya.
sumber
Baru saja menghadiri pertanyaan ini di HackerRank dan inilah Solusi 'Objective C' saya :
Semoga membantu seseorang.
sumber
ini adalah implementasi O (n * lg n) menggunakan implementasi pencarian biner di dalam sebuah loop.
sumber
Dengan python
sumber
Solusi bagus dari Codeaddict. Saya memberanikan diri untuk mengimplementasikan versinya di Ruby:
Untuk mengizinkan pasangan duplikat (1,5), (5,1) kita hanya perlu menghapus
&& !result[sum-l]
instruksinyasumber
Berikut adalah kode Java untuk tiga pendekatan:
1. Menggunakan Map O (n), HashSet juga dapat digunakan di sini.
2. Urutkan array dan kemudian gunakan BinarySearch untuk mencari komplemen O (nLog (n))
3. BruteForce tradisional dua loop O (n ^ 2)
sumber
Program sederhana di java untuk array yang memiliki elemen unik:
sumber
Cuplikan kode Java sederhana untuk mencetak pasangan di bawah ini:
sumber
Solusi lain di Swift: idenya adalah membuat hash yang menyimpan nilai (sum - currentValue) dan membandingkannya dengan nilai loop saat ini. Kompleksitasnya adalah O (n).
sumber
Solusi Saya - Java - Tanpa duplikat
sumber
Ini mencetak pasangan dan menghindari duplikat menggunakan manipulasi bitwise.
sumber
Saya melewati sedikit manuplasi dan hanya membandingkan nilai indeks. Ini kurang dari nilai iterasi loop (i dalam kasus ini). Ini tidak akan mencetak pasangan duplikat dan elemen array duplikat juga.
sumber
di C #:
sumber
Satu Solusi bisa begini, tapi tidak optimul (Kompleksitas kode ini adalah O (n ^ 2)):
sumber
Versi kode python sederhana yang menemukan jumlah pasangan nol dan dapat dimodifikasi untuk menemukan k:
Kompleksitas run time dari fungsi tersebut adalah O (n) dan Spasi: O (n) juga.
sumber
sumber
kurang dari o (n) solusi akan =>
sumber
Solusi dengan Python menggunakan pemahaman daftar
O (N 2 )
juga memberikan dua pasangan terurut- (a, b) dan (b, a) juga
sumber
I am not sure … Thanks for comments
). Anda mungkin menunjukkan tusukan pada kompleksitas yang mendekati O (n²).Saya bisa melakukannya di O (n). Beri tahu saya jika Anda menginginkan jawabannya. Perhatikan itu melibatkan hanya melintasi array sekali tanpa penyortiran, dll ... Saya harus menyebutkan juga bahwa itu mengeksploitasi komutatifitas penambahan dan tidak menggunakan hash tetapi membuang memori.
menggunakan Sistem; menggunakan System.Collections.Generic;
/ * Pendekatan O (n) ada dengan menggunakan tabel pencarian. Pendekatannya adalah dengan menyimpan nilai dalam "bin" yang dapat dengan mudah dicari (misalnya, O (1)) jika itu adalah kandidat untuk jumlah yang sesuai.
misalnya,
untuk setiap a [k] dalam larik kita cukup meletakkannya di larik lain pada lokasi x - a [k].
Misalkan kita memiliki [0, 1, 5, 3, 6, 9, 8, 7] dan x = 9
Kami membuat array baru,
nilai indeks
MAKA satu-satunya nilai yang penting adalah nilai yang memiliki indeks ke dalam tabel baru.
Jadi, katakanlah ketika kita mencapai 9 atau sama, kita melihat apakah array baru kita memiliki indeks 9 - 9 = 0. Karena kita tahu bahwa semua nilai yang dikandungnya akan bertambah menjadi 9. (perhatikan karena ini jelas hanya ada 1 mungkin satu tetapi mungkin memiliki beberapa nilai indeks di dalamnya yang perlu kita simpan).
Jadi secara efektif apa yang akhirnya kita lakukan adalah hanya berpindah melalui array sekali. Karena penambahan bersifat komutatif, kami akan mendapatkan semua hasil yang mungkin.
Misalnya, ketika kita mendapatkan nilai 6 kita mendapatkan indeks ke dalam tabel baru kita sebagai 9 - 6 = 3. Karena tabel tersebut berisi nilai indeks, kita mengetahui nilainya.
Ini pada dasarnya menukar kecepatan untuk memori. * /
sumber
Solusi Javascript:
sumber
https://github.com/clockzhong/findSumPairNumber
Saya melakukannya di bawah biaya kompleksitas O (m + n) untuk waktu dan ruang memori. Saya menduga itu adalah algoritma terbaik sejauh ini.
sumber
int [] arr = {1,2,3,4,5,6,7,8,9,0};
var z = (dari a di arr dari b di arr di mana 10 - a == b pilih baru {a, b}) ToList;
sumber