Temukan sepasang elemen dari larik yang jumlahnya sama dengan bilangan tertentu


122

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--;
        }
    }
}

3
Solusi O (n) dimungkinkan jika Anda membuang semuanya ke dalam kumpulan O (1) dari beberapa jenis alih-alih menyortir larik.
Anon.

1
@Anon Bisakah kamu ceritakan lebih detail, bagaimana membangun set seperti itu?
Gin

3
Gunakan hash. Sebagian besar bahasa akan memiliki HashSet O (1) yang diamortisasi di suatu tempat di perpustakaan standar mereka.
Anon.

15
Sebuah nit kecil - O (nLog (n) + n) adalah O (nLog (n)). Notasi O besar hanya mempertahankan istilah dominan dan menghapus semua istilah orde bawah.
pjs

2
Perhatikan evaluasi korsleting dan pengalamatan off-by-one: while((arr[i] + arr[j]) <= sum && i < j)seharusnya while( i < J && arr[i] + arr[j] <= sum ). (serupa untuk subloop kedua)
wildplasser

Jawaban:


135
# Let arr be the given array.
# And K be the give sum


for i=0 to arr.length - 1 do
  hash(arr[i]) = i  // key is the element and value is its index.
end-for

for i=0 to arr.length - 1 do
  if hash(K - arr[i]) != i  // if Kth element exists and it's different then we found a pair
    print "pair i , hash(K - arr[i]) has sum K"
  end-if
end-for

26
Anda bahkan bisa melakukannya dalam satu iterasi melalui array, dengan meletakkan pernyataan if Anda dari loop kedua, tepat setelah penetapan hash di loop pertama.
Alexander Kondratskiy

4
Catatan kecil: Ini (serta saran Alexander) akan mencetak ganda beberapa pasangan, apakah keunikan suatu pasangan ditentukan oleh indeks (seperti yang dapat disiratkan dari jawaban ini) atau oleh nilai (seperti yang terlihat di OP). Mungkin ada beberapa (O (n ^ 2)) pasangan unik menurut indeks, misalnya 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. +1
William

2
@codaddict Tapi bagaimana jika array sangat besar? Maksud saya kisaran nilai di dalamnya sangat besar? Jadi, solusi hash akan menjadi kurang praktis. Adakah metode alternatif dan optimal untuk hal yang sama?
Prashant Singh

15
Bagaimana jika ada duplikat?
zad

2
Apakah hash(K - arr[i]) != ientah bagaimana memeriksa kehadiran dan kurangnya kecocokan? Saya berharap akan ada pemeriksaan terpisah untuk kehadiran.
Joseph Garvin

185

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.



Bagaimana Anda membuat tabel hash untuk elemen array?
Satish Patel

Lihat tautan yang telah saya bagikan. Kita dapat memiliki array paralel untuk menyimpan elemen sebagai indeks, atau Anda dapat menambahkan elemen ke hashtable dan menggunakan isi di dalamnya. Maaf atas balasan yang terlambat.
kinshuk4

11
Anda mungkin mendapatkan positif palsu jika ada elemen yang tepat setengah dari jumlah target.
Florian F

2
@Florian_F Tidak bisakah Anda hanya kasus khusus di mana Anda memiliki elemen yang persis setengah?
Joseph Garvin

1
@jazzz Maksud saya HashMap di sini, meskipun HashSet juga akan melakukannya. Berikut implementasinya - github.com/kinshuk4/AlgorithmUtil/blob/master/src/com/vaani/… . Semoga membantu.
kinshuk4

64

Implementasi di Java: Menggunakan algoritma codaddict (Mungkin sedikit berbeda)

import java.util.HashMap;

public class ArrayPairSum {


public static void main(String[] args) {        

    int []a = {2,45,7,3,5,1,8,9};
    printSumPairs(a,10);        

}


public static void printSumPairs(int []input, int k){
    Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();

    for(int i=0;i<input.length;i++){

        if(pairs.containsKey(input[i]))
            System.out.println(input[i] +", "+ pairs.get(input[i]));
        else
            pairs.put(k-input[i], input[i]);
    }

}
}

Untuk input = {2,45,7,3,5,1,8,9}dan jika Sum10

Pasangan keluaran:

3,7 
8,2
9,1

Beberapa catatan tentang solusinya:

  • Kami mengulang hanya sekali melalui array -> O (n) waktu
  • Waktu penyisipan dan pencarian di Hash adalah O (1).
  • Waktu keseluruhan adalah O (n), meskipun menggunakan spasi ekstra dalam hal hash.

1
Ini bagus HANYA jika larik input tidak memiliki duplikat.
Naren

2
@Naren: Tidak ada bedanya meskipun ada duplikat dalam larik yang diberikan
abhishek08aug

1
itu tidak mengimplementasikan apa yang ditulis codaddicts, dan apa yang Anda lakukan, meskipun berhasil, tidak perlu rumit. Ini tidak ada artinya 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)}
Adrian Shum

1
Oke terima kasih. Untuk keperluan referensi orang lain, saya baru saja membuat utas lain sehingga yang mengalami kesulitan dalam menganalisis cara kerja solusi ini dapat memahaminya dengan baik. Berikut ini tautannya: stackoverflow.com/questions/33274952/…
Yohanes

2
@ abhishek08aug ini tidak akan berfungsi untuk {1, 1, 1}
jbakirov

8

Solusi di java. Anda dapat menambahkan semua elemen String ke ArrayList string dan mengembalikan daftar tersebut. Di sini saya hanya mencetaknya.

void numberPairsForSum(int[] array, int sum) {
    HashSet<Integer> set = new HashSet<Integer>();
    for (int num : array) {
        if (set.contains(sum - num)) {
            String s = num + ", " + (sum - num) + " add up to " + sum;
            System.out.println(s);
        }
        set.add(num);
    }
}

4

Implementasi Python:

import itertools
list = [1, 1, 2, 3, 4, 5,]
uniquelist = set(list)
targetsum = 5
for n in itertools.combinations(uniquelist, 2):
    if n[0] + n[1] == targetsum:
        print str(n[0]) + " + " + str(n[1])

Keluaran:

1 + 4
2 + 3

2
lihat ke ... akan overhead untuk mencari elemen
Nikhil Rupanawar

4

C ++ 11, kompleksitas run time O (n):

#include <vector>
#include <unordered_map>
#include <utility>

std::vector<std::pair<int, int>> FindPairsForSum(
        const std::vector<int>& data, const int& sum)
{
    std::unordered_map<int, size_t> umap;
    std::vector<std::pair<int, int>> result;
    for (size_t i = 0; i < data.size(); ++i)
    {
        if (0 < umap.count(sum - data[i]))
        {
            size_t j = umap[sum - data[i]];
            result.push_back({data[i], data[j]});
        }
        else
        {
            umap[data[i]] = i;
        }
    }

    return result;
}

3

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.

var count_pairs = function(_arr,x) {
  if(!x) x = 0;
  var pairs = 0;
  var i = 0;
  var k = _arr.length-1;
  if((k+1)<2) return pairs;
  var halfX = x/2; 
  while(i<k) {
    var curK = _arr[k];
    var curI = _arr[i];
    var pairsThisLoop = 0;
    if(curK+curI==x) {
      // if midpoint and equal find combinations
      if(curK==curI) {
        var comb = 1;
        while(--k>=i) pairs+=(comb++);
        break;
      }
      // count pair and k duplicates
      pairsThisLoop++;
      while(_arr[--k]==curK) pairsThisLoop++;
      // add k side pairs to running total for every i side pair found
      pairs+=pairsThisLoop;
      while(_arr[++i]==curI) pairs+=pairsThisLoop;
    } else {
      // if we are at a mid point
      if(curK==curI) break;
      var distK = Math.abs(halfX-curK);
      var distI = Math.abs(halfX-curI);
      if(distI > distK) while(_arr[++i]==curI);
      else while(_arr[--k]==curK);
    }
  }
  return pairs;
}

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

  • temukan pasangannya
  • temukan pasangan <x
  • temukan pasangan> x

Nikmati!


Apa fungsi baris ini ?: if(distI > distK) while(_arr[++i]==curI); else while(_arr[--k]==curK);
Yuriy Chernyshov

Garis-garis ini melewati nilai duplikat dari kedua sisi dan menghitungnya sebagai pasangan jika mereka adalah bagian dari pasangan sum = N
Drone Brain

3

Di)

def find_pairs(L,sum):
    s = set(L)
    edgeCase = sum/2
    if L.count(edgeCase) ==2:
        print edgeCase, edgeCase
    s.remove(edgeCase)      
    for i in s:
        diff = sum-i
        if diff in s: 
            print i, diff


L = [2,45,7,3,5,1,8,9]
sum = 10          
find_pairs(L,sum)

Metodologi: a + b = c, jadi daripada mencari (a, b) kita mencari a = c - b


Tidak wajan jika Anda memiliki duplikat dalam input, seperti ini: [3, 4, 3, 2, 5] dan jumlah = 6
Anton Danilchenko

Koreksi semua kasus tepi, sekarang coba
garg10may

2

Implementasi di Java: Menggunakan algoritma codaddict:

import java.util.Hashtable;
public class Range {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Hashtable mapping = new Hashtable();
    int a[]= {80,79,82,81,84,83,85};
    int k = 160;

    for (int i=0; i < a.length; i++){
        mapping.put(a[i], i);
    }

    for (int i=0; i < a.length; i++){
        if (mapping.containsKey(k - a[i]) && (Integer)mapping.get(k-a[i]) != i){
            System.out.println(k-a[i]+", "+ a[i]);
        }
    }      

}

}

Keluaran:

81, 79
79, 81

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.


untuk C # ini mungkin berhasil - int k = 16; int hitung = 0; int [] intArray = {5, 7, 11, 23,8,9,15,1,10,6}; untuk (int i = 0; i <intArray.Length; i ++) {for (int j = i; j <intArray.Length; j ++) {if ((k - intArray [i]) == intArray [j]) { hitung ++; }}} Console.WriteLine (menghitung);
MukulSharma

2

Baru saja menghadiri pertanyaan ini di HackerRank dan inilah Solusi 'Objective C' saya :

-(NSNumber*)sum:(NSArray*) a andK:(NSNumber*)k {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    long long count = 0;
    for(long i=0;i<a.count;i++){

        if(dict[a[i]]) {
            count++;
            NSLog(@"a[i]: %@, dict[array[i]]: %@", a[i], dict[a[i]]);
        }
        else{
            NSNumber *calcNum = @(k.longLongValue-((NSNumber*)a[i]).longLongValue);
            dict[calcNum] = a[i];
        }

    }
    return @(count);
}

Semoga membantu seseorang.


sintaks kode lebih sulit untuk dipahami daripada algoritma itu sendiri! :)
Rajendra Uppal

1

ini adalah implementasi O (n * lg n) menggunakan implementasi pencarian biner di dalam sebuah loop.

#include <iostream>

using namespace std;

bool *inMemory;


int pairSum(int arr[], int n, int k)
{
    int count = 0;

    if(n==0)
        return count;
    for (int i = 0; i < n; ++i)
    {
        int start = 0;
        int end = n-1;      
        while(start <= end)
        {
            int mid = start + (end-start)/2;
            if(i == mid)
                break;
            else if((arr[i] + arr[mid]) == k && !inMemory[i] && !inMemory[mid])
            {
                count++;
                inMemory[i] = true;
                inMemory[mid] = true;
            }
            else if(arr[i] + arr[mid] >= k)
            {
                end = mid-1;
            }
            else
                start = mid+1;
        }
    }
    return count;
}


int main()
{
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    inMemory = new bool[10];
    for (int i = 0; i < 10; ++i)
    {
        inMemory[i] = false;
    }
    cout << pairSum(arr, 10, 11) << endl;
    return 0;
}

1

Dengan python

arr = [1, 2, 4, 6, 10]
diff_hash = {}
expected_sum = 3
for i in arr:
    if diff_hash.has_key(i):
        print i, diff_hash[i]
    key = expected_sum - i
    diff_hash[key] = i

1

Solusi bagus dari Codeaddict. Saya memberanikan diri untuk mengimplementasikan versinya di Ruby:

def find_sum(arr,sum)
 result ={}
 h = Hash[arr.map {|i| [i,i]}]
 arr.each { |l| result[l] = sum-l  if h[sum-l] && !result[sum-l]  }
 result
end

Untuk mengizinkan pasangan duplikat (1,5), (5,1) kita hanya perlu menghapus && !result[sum-l]instruksinya


1

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)

public class PairsEqualToSum {

public static void main(String[] args) {
    int a[] = {1,10,5,8,2,12,6,4};
    findPairs1(a,10);
    findPairs2(a,10);
    findPairs3(a,10);

}


//Method1 - O(N) use a Map to insert values as keys & check for number's complement in map
    static void findPairs1(int[]a, int sum){
        Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
        for(int i=0; i<a.length; i++){
            if(pairs.containsKey(sum-a[i]))
                System.out.println("("+a[i]+","+(sum-a[i])+")");
            else
               pairs.put(a[i], 0);
        }
    }



//Method2 - O(nlog(n)) using Sort
static void findPairs2(int[]a, int sum){
        Arrays.sort(a);
        for(int i=0; i<a.length/2; i++){
            int complement = sum - a[i];
            int foundAtIndex = Arrays.binarySearch(a,complement);
            if(foundAtIndex >0 && foundAtIndex != i) //to avoid situation where binarySearch would find the original and not the complement like "5"
                System.out.println("("+a[i]+","+(sum-a[i])+")");
        }
 }

//Method 3 - Brute Force O(n^2)
static void findPairs3(int[]a, int sum){

    for(int i=0; i<a.length; i++){
        for(int j=i; j<a.length;j++){
            if(a[i]+a[j] == sum)
                System.out.println("("+a[i]+","+a[j]+")");
        }
    }
}

}

1

Program sederhana di java untuk array yang memiliki elemen unik:

import java.util.*;
public class ArrayPairSum {
    public static void main(String[] args) { 
        int []a = {2,4,7,3,5,1,8,9,5};
        sumPairs(a,10);  
    }

    public static void sumPairs(int []input, int k){
      Set<Integer> set = new HashSet<Integer>();    
      for(int i=0;i<input.length;i++){

        if(set.contains(input[i]))
            System.out.println(input[i] +", "+(k-input[i]));
        else
            set.add(k-input[i]);
       }
    }
}

1

Cuplikan kode Java sederhana untuk mencetak pasangan di bawah ini:

    public static void count_all_pairs_with_given_sum(int arr[], int S){
        if(arr.length < 2){
        return;
    }        
    HashSet values = new HashSet(arr.length);
    for(int value : arr)values.add(value);
    for(int value : arr){
        int difference = S - value;
    if(values.contains(difference) && value<difference){
        System.out.printf("(%d, %d) %n", value, difference);
        }
    }
    }

1

Solusi lain di Swift: idenya adalah membuat hash yang menyimpan nilai (sum - currentValue) dan membandingkannya dengan nilai loop saat ini. Kompleksitasnya adalah O (n).

func findPair(list: [Int], _ sum: Int) -> [(Int, Int)]? {
    var hash = Set<Int>() //save list of value of sum - item.
    var dictCount = [Int: Int]() //to avoid the case A*2 = sum where we have only one A in the array
    var foundKeys  = Set<Int>() //to avoid duplicated pair in the result.

    var result = [(Int, Int)]() //this is for the result.
    for item in list {

        //keep track of count of each element to avoid problem: [2, 3, 5], 10 -> result = (5,5)
        if (!dictCount.keys.contains(item)) {
            dictCount[item] = 1
        } else {
            dictCount[item] = dictCount[item]! + 1
        }

        //if my hash does not contain the (sum - item) value -> insert to hash.
        if !hash.contains(sum-item) {
            hash.insert(sum-item)
        }

        //check if current item is the same as another hash value or not, if yes, return the tuple.
        if hash.contains(item) &&
            (dictCount[item] > 1 || sum != item*2) // check if we have item*2 = sum or not.
        {
            if !foundKeys.contains(item) && !foundKeys.contains(sum-item) {
                foundKeys.insert(item) //add to found items in order to not to add duplicated pair.
                result.append((item, sum-item))
            }
        }
    }
    return result
}

//test:
let a = findPair([2,3,5,4,1,7,6,8,9,5,3,3,3,3,3,3,3,3,3], 14) //will return (8,6) and (9,5)

1

Solusi Saya - Java - Tanpa duplikat

    public static void printAllPairSum(int[] a, int x){
    System.out.printf("printAllPairSum(%s,%d)\n", Arrays.toString(a),x);
    if(a==null||a.length==0){
        return;
    }
    int length = a.length;
    Map<Integer,Integer> reverseMapOfArray = new HashMap<>(length,1.0f);
    for (int i = 0; i < length; i++) {
        reverseMapOfArray.put(a[i], i);
    }

    for (int i = 0; i < length; i++) {
        Integer j = reverseMapOfArray.get(x - a[i]);
        if(j!=null && i<j){
            System.out.printf("a[%d] + a[%d] = %d + %d = %d\n",i,j,a[i],a[j],x);
        }
    }
    System.out.println("------------------------------");
}

0

Ini mencetak pasangan dan menghindari duplikat menggunakan manipulasi bitwise.

public static void findSumHashMap(int[] arr, int key) {
    Map<Integer, Integer> valMap = new HashMap<Integer, Integer>();
    for(int i=0;i<arr.length;i++)
        valMap.put(arr[i], i);

    int indicesVisited = 0; 
    for(int i=0;i<arr.length;i++) {
        if(valMap.containsKey(key - arr[i]) && valMap.get(key - arr[i]) != i) {
            if(!((indicesVisited & ((1<<i) | (1<<valMap.get(key - arr[i])))) > 0)) {
                int diff = key-arr[i];
                System.out.println(arr[i] + " " +diff);
                indicesVisited = indicesVisited | (1<<i) | (1<<valMap.get(key - arr[i]));
            }
        }
    }
}

0

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.

public static void findSumHashMap(int[] arr, int key) {
    Map<Integer, Integer> valMap = new HashMap<Integer, Integer>();
    for (int i = 0; i < arr.length; i++) {
        valMap.put(arr[i], i);
    }
    for (int i = 0; i < arr.length; i++) {
        if (valMap.containsKey(key - arr[i])
                && valMap.get(key - arr[i]) != i) {
            if (valMap.get(key - arr[i]) < i) {
                int diff = key - arr[i];
                System.out.println(arr[i] + " " + diff);
            }
        }
    }
}

0

di C #:

        int[] array = new int[] { 1, 5, 7, 2, 9, 8, 4, 3, 6 }; // given array
        int sum = 10; // given sum
        for (int i = 0; i <= array.Count() - 1; i++)
            if (array.Contains(sum - array[i]))
                Console.WriteLine("{0}, {1}", array[i], sum - array[i]);

jawaban ini akan lebih berguna jika Anda menjelaskan urutan pertumbuhan solusi Anda
Thomas

0

Satu Solusi bisa begini, tapi tidak optimul (Kompleksitas kode ini adalah O (n ^ 2)):

public class FindPairsEqualToSum {

private static int inputSum = 0;

public static List<String> findPairsForSum(int[] inputArray, int sum) {
    List<String> list = new ArrayList<String>();
    List<Integer> inputList = new ArrayList<Integer>();
    for (int i : inputArray) {
        inputList.add(i);
    }
    for (int i : inputArray) {
        int tempInt = sum - i;
        if (inputList.contains(tempInt)) {
            String pair = String.valueOf(i + ", " + tempInt);
            list.add(pair);
        }
    }
    return list;
   }
}

0

Versi kode python sederhana yang menemukan jumlah pasangan nol dan dapat dimodifikasi untuk menemukan k:

def sumToK(lst):
    k = 0  # <- define the k here
    d = {} # build a dictionary 

# build the hashmap key = val of lst, value = i
for index, val in enumerate(lst):
    d[val] = index

# find the key; if a key is in the dict, and not the same index as the current key
for i, val in enumerate(lst):
    if (k-val) in d and d[k-val] != i:
        return True

return False

Kompleksitas run time dari fungsi tersebut adalah O (n) dan Spasi: O (n) juga.


0
 public static int[] f (final int[] nums, int target) {
    int[] r = new int[2];
    r[0] = -1;
    r[1] = -1;
    int[] vIndex = new int[0Xfff];
    for (int i = 0; i < nums.length; i++) {
        int delta = 0Xff;
        int gapIndex = target - nums[i] + delta;
        if (vIndex[gapIndex] != 0) {
            r[0] = vIndex[gapIndex];
            r[1] = i + 1;
            return r;
        } else {
            vIndex[nums[i] + delta] = i + 1;
        }
    }
    return r;
}

0

kurang dari o (n) solusi akan =>

function(array,k)
          var map = {};
          for element in array
             map(element) = true;
             if(map(k-element)) 
                 return {k,element}

Akan gagal untuk input tertentu. Ditambah Anda diminta untuk mengembalikan jumlah yang tidak paris
Aviad

0

Solusi dengan Python menggunakan pemahaman daftar

f= [[i,j] for i in list for j in list if j+i==X];

O (N 2 )

juga memberikan dua pasangan terurut- (a, b) dan (b, a) juga


Anda dapat menyebutkan sebuah bahasa, apakah pasangan (a, b) dan (b, a) unik, dan pertanyaan apa yang dijawab ini (pertanyaan tidak mengandung yang eksplisit - I am not sure … Thanks for comments). Anda mungkin menunjukkan tusukan pada kompleksitas yang mendekati O (n²).
greybeard

0

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

9 - 0 = 9     0
9 - 1 = 8     1
9 - 5 = 4     5
9 - 3 = 6     3
9 - 6 = 3     6
9 - 9 = 0     9
9 - 8 = 1     8
9 - 7 = 2     7

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. * /

namespace sum
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 25;
            int X = 10;
            var arr = new List<int>();
            for(int i = 0; i <= num; i++) arr.Add((new Random((int)(DateTime.Now.Ticks + i*num))).Next(0, num*2));
            Console.Write("["); for (int i = 0; i < num - 1; i++) Console.Write(arr[i] + ", "); Console.WriteLine(arr[arr.Count-1] + "] - " + X);
            var arrbrute = new List<Tuple<int,int>>();
            var arrfast = new List<Tuple<int,int>>();

            for(int i = 0; i < num; i++)
            for(int j = i+1; j < num; j++)
                if (arr[i] + arr[j] == X) 
                    arrbrute.Add(new Tuple<int, int>(arr[i], arr[j]));




            int M = 500;
            var lookup = new List<List<int>>();
            for(int i = 0; i < 1000; i++) lookup.Add(new List<int>());
            for(int i = 0; i < num; i++)        
            {
                // Check and see if we have any "matches"
                if (lookup[M + X - arr[i]].Count != 0)
                {
                    foreach(var j in lookup[M + X - arr[i]])
                    arrfast.Add(new Tuple<int, int>(arr[i], arr[j])); 
                }

                lookup[M + arr[i]].Add(i);

            }

            for(int i = 0; i < arrbrute.Count; i++)
                Console.WriteLine(arrbrute[i].Item1 + " + " + arrbrute[i].Item2 + " = " + X);
            Console.WriteLine("---------");
            for(int i = 0; i < arrfast.Count; i++)
                Console.WriteLine(arrfast[i].Item1 + " + " + arrfast[i].Item2 + " = " + X);

            Console.ReadKey();
        }
    }
}

Pada dasarnya untuk menghindari hash kita harus membuat tabel yang dapat menerima penyisipan acak pada indeks yang agak sewenang-wenang. Oleh karena itu saya menggunakan M untuk memastikan bahwa ada cukup elemen dan mengalokasikan sebelumnya set yang berdekatan meskipun sebagian besar tidak akan digunakan. Sebuah set hash akan menangani ini secara langsung.
AbstractDissonance

Jadi, Anda menggunakan set hash dengan fungsi hash sederhana dan ukurannya lebih besar dari nilai maksimal fungsi hash Anda?
Chris Hopman

Juga mungkin juga menggunakan fungsi identitas untuk fungsi hash Anda pada saat ini. Artinya, letakkan a [k] di "bin" a [k] -th.
Chris Hopman

Karena a [k] dan X - a [k] digunakan sebagai indeks dan saya menggunakan array, artinya indeks minimum tidak boleh 0. Oleh karena itu, saya cukup menambahkan angka yang sangat besar untuk menggesernya ke atas. Jika seseorang dapat membuat fungsi hash yang berfungsi untuk nilai arbitrer maka mereka dapat menggunakan daftar sederhana tanpa harus melakukan pengalihan ini. Pergeseran + pra-alokasi membantu menghindari keharusan membuat hash (atau bisa dianggap sebagai hash yang sangat sederhana (dan cepat)).
AbstractDissonance

-1

Solusi Javascript:

var sample_input = [0, 1, 100, 99, 0, 10, 90, 30, 55, 33, 55, 75, 50, 51, 49, 50, 51, 49, 51];
var result = getNumbersOf(100, sample_input, true, []);

function getNumbersOf(targetNum, numbers, unique, res) {
    var number = numbers.shift();

    if (!numbers.length) {
        return res;
    }

    for (var i = 0; i < numbers.length; i++) {
        if ((number + numbers[i]) === targetNum) {
            var result = [number, numbers[i]];
            if (unique) {
              if (JSON.stringify(res).indexOf(JSON.stringify(result)) < 0) {
                res.push(result);                
              }
            } else {
              res.push(result);
            }
            numbers.splice(numbers.indexOf(numbers[i]), 1);
            break;
        }
    }
    return getNumbersOf(targetNum, numbers, unique, res);
}

Sangat enifficient .... Anda menggunakan Stringify (O (n) waktu dan ruang) setiap iterasi ..
Aviad


-4

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;

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.