web-dev-qa-db-de.com

Gibt eine Liste von Zahlen und eine Zahl k an, wird zurückgegeben, ob sich zwei Zahlen aus der Liste zu k addieren

Diese Frage wurde im Google-Programmierinterview gestellt. Ich dachte an zwei Ansätze für dasselbe:

  1. Finde alle Unterfolgen der Länge. Berechnen Sie dabei die Summe und der beiden Elemente und prüfen Sie, ob es gleich k ist. Wenn ja, drucken Sie Ja, sonst suchen Sie weiter. Dies ist ein brutaler Force-Ansatz.

  2. Sortieren Sie das Array in nicht absteigender Reihenfolge. Beginnen Sie dann, das Array von seinem rechten Ende aus zu durchlaufen. Nehmen wir an, wir haben das sortierte Array {3,5,7,10}, und wir wollen, dass die Summe 17 ist. Wir beginnen mit Element 10, Index = 3, nennen wir den Index mit 'j'. Fügen Sie dann das aktuelle Element ein und berechnen Sie required_sum = sum - current_element. Danach können wir eine binäre oder ternäre Suche in Array [0- (j-1)] durchführen, um herauszufinden, ob es ein Element gibt, dessen Wert gleich der erforderlichen Summe ist. Wenn wir ein solches Element finden, können wir brechen, da wir eine Untersequenz der Länge 2 gefunden haben, deren Summe die gegebene Summe ist. Wenn wir kein solches Element finden, verringern Sie den Index von j und wiederholen Sie die oben genannten Schritte für das resultierende Subarray mit length = length-1, d. H. 

Hier haben wir angenommen, dass das Array sowohl negative als auch positive ganze Zahlen haben könnte.

Können Sie eine bessere Lösung als diese vorschlagen? Eine DP-Lösung vielleicht? Eine Lösung, die die Zeitkomplexität weiter reduzieren kann.

9
Jhanak Didwania

Diese Frage kann leicht mit Hilfe von set in O(N) Zeit und Raumkomplexität gelöst werden. Zuerst fügen Sie alle Elemente des Arrays in set hinzu und durchlaufen dann jedes Element des Arrays und überprüfen, ob K-ar ist im Set vorhanden oder nicht. 

Hier ist der Code in Java mit O(N) Komplexität:

boolean flag=false;
HashSet<Long> hashSet = new HashSet<>();
for(int i=0;i<n;i++){
    if(hashSet.contains(k-ar[i]))flag=true;
    hashSet.add(ar[i]);
}
if(flag)out.println("YES PRESENT");
else out.println("NOT PRESENT");
11
NIKUNJ KHOKHAR

Hier ist eine Java-Implementierung mit derselben zeitlichen Komplexität wie der zum Sortieren des Arrays verwendete Algorithmus. Beachten Sie, dass dies schneller ist als Ihre zweite Idee, da wir nicht jedes Mal das gesamte Array nach einem passenden Partner durchsuchen müssen, wenn wir eine Zahl prüfen.

public static boolean containsPairWithSum(int[] a, int x) {
    Arrays.sort(a);
    for (int i = 0, j = a.length - 1; i < j;) {
        int sum = a[i] + a[j];
        if (sum < x)
            i++;
        else if (sum > x)
            j--;
        else
            return true;
    }
    return false;
}
11
Niki

Dies ist eine Java-Implementierung mit O(n) Zeitkomplexität und O(n) Speicherplatz. Die Idee ist, eine HashMap zu haben, die Komplemente von jedem Array-Element mit Ziel. Wenn das Komplement gefunden wird, haben wir zwei Array-Elemente, die sich zum Ziel summieren.

 public boolean twoSum(int[] nums, int target) {
    if(nums.length == 0 || nums == null) return false;

    Map<Integer, Integer> complementMap = new HashMap<>();

    for (int i = 0; i < nums.length; i++) {
         int curr = nums[i];
         if(complementMap.containsKey(target - curr)){
           return true;
         }
    complementMap.put(curr, i);
    }
  return false;
}
4
spiralarchitect

wenn Sie die Anzahl der Paare ermitteln möchten,

pairs = [3,5,7,10]
k = 17
counter = 0

for i in pairs:
    if k - i in pairs:
        counter += 1

print(counter//2)
2
Ilkin

Mit Scala in einem einzigen Durchgang mit O(n) Zeit und Raumkomplexität.

import collection.mutable.HashMap

def addUpToK(arr: Array[Int], k: Int): Option[Int] = {

val arrayHelper = new HashMap[Int,Int]()

def addUpToKHelper( i: Int): Option[Int] = {
  if(i < arr.length){
    if(arrayHelper contains k-arr(i) ){
      Some(arr(i))
    }else{
      arrayHelper += (arr(i) -> (k-arr(i)) )
      addUpToKHelper( i+1)
    }

  }else{
   None
  }
}
addUpToKHelper(0)
}

addUpToK(Array(10, 15, 3, 7), 17)
1
satya_fury

Die Lösung kann in nur einem Durchgang des Arrays gefunden werden. Initialisieren Sie ein Hash-Set und beginnen Sie, das Array zu iterieren. Wenn das aktuelle Element im Array in der Gruppe gefunden wird, geben Sie true zurück. Andernfalls fügen Sie der Gruppe das Komplement dieses Elements (x-arr [i]) hinzu. Wenn die Iteration des Arrays beendet wurde, ohne zurückzukehren, bedeutet dies, dass es kein solches Paar gibt, dessen Summe gleich x ist.

  public boolean containsPairWithSum(int[] a, int x) {
    Set<Integer> set = new HashSet<>();
    for (int i = 0; i< a.length; i++) {
        if(set.contains(a[i])) 
            return true;
        set.add(x - a[i]);
    }
    return false;
 }

Hier ist die Implementierung von Python

arr=[3,5,7,10]
k=17
flag=False
for i in range(0,len(arr)):
    if k-arr[i] in arr:
      flag=True
print( flag )
1
Saurabh

C++ - Lösung: 

int main(){

    int n;
    cin>>n;
    int arr[n];
    for(int i = 0; i < n; i++)
    {
        cin>>arr[i];
    }
    int k;
    cin>>k;
    int t = false;
    for(int i = 0; i < n-1; i++)
    {
        int s = k-arr[i];
        for(int j = i+1; j < n; j++)
        {
            if(s==arr[j])
            t=true;
        }

    }       
    if (t){
        cout<<"Thank you C++, very cool";
    }
    else{
        cout<<"Damn it!";
    }
        return 0;
}
1
Dev Tech

Javascript-Lösung:

function hasSumK(arr, k) {
    hashMap = {};
    for (let value of arr) {
        if (hashMap[value]) { return true;} else { hashMap[k - value] = true };
    }
    return false;
}
1
Leo Kamwathi

Ich habe zwei Lösungen in C++ gefunden. Einer war ein naiver Brute-Force-Typ, der sich in der Zeit O (n ^ 2) befand.

int main() {
int N,K;
vector<int> list;
cin >> N >> K;
clock_t tStart = clock();   
for(int i = 0;i<N;i++) {
    list.Push_back(i+1);
}

for(int i = 0;i<N;i++) {
    for(int j = 0;j<N;j++) {
        if(list[i] + list[j] == K) {
            cout << list[i] << " " << list[j] << endl;
            cout << "YES" << endl;
            printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
            return 0;
        }
    }
}
cout << "NO" << endl;

printf("Time taken: %f\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);

return 0;}

Diese Lösung, wie Sie sich vorstellen können, wird bei höheren Eingabewerten viel Zeit in Anspruch nehmen.

Meine zweite Lösung konnte ich in O(N) Zeit implementieren. Mit einem unordered_set, ähnlich der obigen Lösung.

#include <iostream>
#include <unordered_set>
#include <time.h>

using namespace std;

int main() {
    int N,K;
    int trig = 0;
    int a,b;
    time_t tStart = clock();
    unordered_set<int> u;
    cin >> N >> K;
    for(int i =  1;i<=N;i++) {
        if(u.find(abs(K - i)) != u.end()) {
            trig = 1;
            a = i;
            b = abs(K - i);
        }
        u.insert(i);
    }
    trig ? cout << "YES" : cout << "NO";
    cout << endl;
    cout << a << " " << b << endl;
    printf("Time taken %fs\n",(double) (clock() - tStart)/CLOCKS_PER_SEC);
    return 0;
}
1
Jimmy lemieux
    function check(arr,k){
    var result = false;
    for (var i=0; i < arr.length; i++){
        for (var j=i+1; j < arr.length; j++){
            result = arr[i] + arr[j] == k;
            console.log(`${arr[i]} + ${arr[j]} = ${arr[i] + arr[j]}`);      
        if (result){
            break;
        }
    }
    return result;
}

Javascript.

1
Nifemi Sola-Ojo

Python-Code:

L = list(map(int,input("Enter List: ").split()))
k = int(input("Enter value: "))

for i in L:
    if (k - i) in L:
        print("True",k-i,i)
1

Python

def add(num, k):
for i in range(len(num)):
    for j in range(len(num)):
        if num[i] + num[j] == k:
            return True
return False
1
Omkar

Hier ist Python. Auf). Das aktuelle Element muss während der Schleife entfernt werden, da die Liste möglicherweise keine doppelten Nummern enthält.

def if_sum_is_k(list, k):
i = 0
list_temp = list.copy()
match = False
for e in list:
    list_temp.pop(i)
    if k - e in list_temp:
        match = True
    i += 1
    list_temp = list.copy()
return match
1
Haobin Liang

Hier ist eine C-Implementierung
Zum Sortieren von O (n2) zeitliche und räumliche Komplexität.
Zur Lösung des Problems verwenden wir Single Pass mit O(n) Zeit- und Raumkomplexität über Rekursion.
/* Bei einer Liste von Zahlen und einer Zahl k geben Sie zwei beliebige Zahlen aus der Liste zurück und addieren sich zu k . Geben Sie [10,15,3,7] und k von 17 ein, geben Sie 10 + 7 zurück ist 17. Bonus: Können Sie es in einem Durchgang tun? * /

#include<stdio.h>
int rec(int i , int j ,int k , int n,int array[])
{
  int sum;
  for( i = 0 ; i<j ;)
  {
      sum = array[i] + array[j];
      if( sum > k)
      {
        j--;
      }else if( sum < k)
      {
        i++;
      }else if( sum == k )
      {
        printf("Value equal to sum of array[%d]  = %d and array[%d] = %d",i,array[i],j,array[j]);
        return 1;//True
      }
  }
  return 0;//False
  }
int main()
  {
  int n ;
  printf("Enter The Value of Number of Arrays = ");
  scanf("%d",&n);
  int array[n],i,j,k,x;
  printf("Enter the Number Which you Want to search in addition of Two Number = ");
  scanf("%d",&x);
  printf("Enter The Value of Array \n");
  for( i = 0 ; i <=n-1;i++)
  {
    printf("Array[%d] = ",i);
    scanf("%d",&array[i]);
  }
  //Sorting of Array
  for( i = 0 ; i <=n-1;i++)
  {
     for( j = 0 ; j <=n-i-1;j++)
     {
     if( array[j]>array[j+1])
     {
       //swapping of two using bitwise operator
       array[j] = array[j]^array[j+1];
       array[j+1] = array[j]^array[j+1];
       array[j] = array[j]^array[j+1];
    }
    }
  }
  k = x ;
  j = n-1;
  rec(i,j,k,n,array);
  return 0 ;
}

AUSGABE

Enter The Value of Number of Arrays = 4
Enter the Number Which you Want to search in addition of Two Number = 17
Enter The Value of Array
Array[0] = 10
Array[1] = 15
Array[2] = 3
Array[3] = 7
Value equal to sum of array[1]  = 7 and array[2] = 10
Process returned 0 (0x0)   execution time : 54.206 s
Press any key to continue.
1
Rishabh Jain

Python-Lösung:

def FindPairs(arr, k):
    for i in range(0, len(arr)):
        if k - arr[i] in arr:
            return True
    return False        
A = [1, 4, 45, 6, 10, 8]
n = 100
print(FindPairs(A, n))

Oder

def findpair(list1, k):
    for i in range(0, len(list1)):
        for j in range(0, len(list1)):
            if k == list1[i] + list1[j]:
                return True    
    return False       
nums = [10, 5, 6, 7, 3]
k = 100
print(findpair(nums, k))
1
Sanjay

Meine C # -Implementierung:

 bool  isPairPresent(int[] numbers,int value)
 {
        for (int i = 0; i < numbers.Length; i++)
        {
            for (int j = 0; j < numbers.Length; j++)
            {
                if (value - numbers[i] == numbers[j])
                    return true;
            }
        }
        return false;
 }
0
R.M. SUHAIL

Meine Antwort auf das Daily Coding Problem

# Python 2.7
def pairSumK (arr, goal):
  return any(map(lambda x: (goal - x) in arr, arr))

arr = [10, 15, 3, 7]
print pairSumK(arr, 17)
0
Gastón Marsano

lösung in Javascript

Diese Funktion nimmt 2 Parameter und durchläuft die Länge der Liste und innerhalb der Schleife gibt es eine weitere Schleife, die eine Zahl zu anderen Zahlen in der Liste hinzufügt und dort die Summe prüft, ob sie gleich k ist oder nicht

const list = [10, 15, 3, 7];
const k = 17;

function matchSum(list, k){
 for (var i = 0; i < list.length; i++) {
  list.forEach(num => {
   if (num != list[i]) {
    if (list[i] + num == k) {
     console.log(`${num} + ${list[i]} = ${k} (true)`);
    }
   }
  })
 }
}

matchSum(list, k);
0
Hassan

Hier ist der Code in Python 3.7 mit O(N) Komplexität:

            def findsome(arr,k):
                if  len(arr)<2:
                    return False;
                for e in arr:
                    if k>e and (k-e) in arr:
                        return True
                return False

und auch Best-Case-Code in Python 3.7 mit O (N ^ 2) -Komplexität:

            def findsomen2 (arr,k):
                if  len(arr)>1:
                    j=0
                    if arr[j] <k:
                        while j<len(arr):
                            i =0
                            while i < len(arr):
                                if arr[j]+arr[i]==k:
                                    return True
                                i +=1
                            j +=1
                return False
0

Python-Implementierung: Der Code würde mit O(n) Komplexität bei Verwendung von Dictionary ausgeführt. Wir würden den (wish_output - current_input) als Schlüssel im Wörterbuch speichern. Und dann würden wir prüfen, ob die Nummer im Wörterbuch vorhanden ist oder nicht. Die Suche in einem Wörterbuch hat eine durchschnittliche Komplexität als O (1).

def PairToSumK(numList,requiredSum):
    dictionary={}
    for num in numList:
        if requiredSum-num not in dictionary:
            dictionary[requiredSum-num]=0
        if num in dictionary:
            print(num,requiredSum-num)
            return True
    return False

arr=[10, 5, 3, 7, 3]
print(PairToSumK(arr,6))
0
Shashank Bhagat

Mit der vavr Bibliothek kann dies auf ziemlich prägnante Weise geschehen:

List<Integer> numbers = List(10, 15, 3, 7);
int k = 17;
boolean twoElementsFromTheListAddUpToK = numbers
                .filter(number -> number < k)
                .crossProduct()
                .map(Tuple -> Tuple._1 + Tuple._2)
                .exists(number -> number == k);
0
k13i

Ich habe mit Scala umgesetzt

  def hasSome(xs: List[Int], k: Int): Boolean = {
    def check(xs: List[Int], k: Int, expectedSet: Set[Int]): Boolean = {
      xs match {
        case List() => false
        case head :: _ if expectedSet contains head => true
        case head :: tail => check(tail, k, expectedSet + (k - head))
      } 
    }
    check(xs, k, Set())
  }
0
khacsinhcs

Hier ist eine Javascript-Lösung:

function ProblemOne_Solve()
{
    const k = 17;
    const values = [10, 15, 3, 8, 2];
    for (i=0; i<values.length; i++) {
        if (values.find((sum) => { return k-values[i] === sum} )) return true;
    }
    return false;
}
0
robertmkc

Hier ist Swift Lösung:

func checkTwoSum(array: [Int], k: Int) -> Bool {
    var foundPair = false
    for n in array {
        if array.contains(k - n) {
            foundPair = true
            break
        } else {
            foundPair = false
        }
    }

    return foundPair
}
0
Mike

C # -Lösung:

bool flag = false;
            var list = new List<int> { 10, 15, 3, 4 };
            Console.WriteLine("Enter K");
            int k = int.Parse(Console.ReadLine());

            foreach (var item in list)
            {
                flag = list.Contains(k - item);
                if (flag)
                {
                    Console.WriteLine("Result: " + flag);
                    return;
                }
            }
            Console.WriteLine(flag);
0
thegautamnayak

Javascript

const findPair = (array, k) => {
  array.sort((a, b) => a - b);
  let left = 0;
  let right = array.length - 1;

  while (left < right) {
    const sum = array[left] + array[right];
    if (sum === k) {
      return true;
    } else if (sum < k) {
      left += 1;
    } else {
      right -= 1;
    }
  }

  return false;
}
0
Frankline20

Javascript-Lösung

function matchSum(arr, k){
  for( var i=0; i < arr.length; i++ ){
    for(var j= i+1; j < arr.length; j++){
       if (arr[i] + arr[j] === k){
        return true;
      }
     }
    }
    return false;
  }
0
Brixton Mavu

Hier sind zwei sehr schnelle Python-Implementierungen (die den Fall berücksichtigen, dass Eingaben von [1,2] und 2 false zurückgeben sollten; mit anderen Worten, Sie können eine Zahl nicht einfach verdoppeln, da sie "zwei" angibt).

Dieser erste durchläuft die Liste der Begriffe und fügt jeden Begriff allen zuvor gesehenen Begriffen hinzu, bis er die gewünschte Summe erreicht.

def do_they_add(terms, result):
    first_terms = []
    for second_term in terms:
        for first_term in first_terms:
            if second_term + first_term == result:
                return True
        first_terms.append(second_term)
    return False

Dieser subtrahiert jeden Begriff vom Ergebnis, bis er eine Differenz erreicht, die in der Liste der Begriffe enthalten ist (unter Verwendung der Regel a+b=c -> c-a=b). Die Verwendung von enumerate und der Indexierung der ungeraden Liste dient dazu, den aktuellen Wert für den ersten Satz dieser Antwort auszuschließen.

def do_they_add_alt(terms, result):
    for i, term in enumerate(terms):
        diff = result - term
        if diff in [*terms[:i - 1], *terms[i + 1:]]:
            return True
    return False

Wenn Sie das Hinzufügen einer Nummer zulassen, kann die zweite Implementierung folgendermaßen vereinfacht werden:

def do_they_add_alt(terms, result):
    for term in terms:
        diff = result - term
        if diff in terms:
            return True
    return False
0
Ian

Ich habe die Lösung in Go Lang ausprobiert. Es verbraucht jedoch O (n ^ 2) Zeit.

package main

import "fmt"

func twoNosAddUptoK(arr []int, k int) bool{
    // O(N^2)
    for i:=0; i<len(arr); i++{
        for j:=1; j<len(arr);j++ {
            if arr[i]+arr[j] ==k{
                return true
            }
        }
    }
    return false
}

func main(){
    xs := []int{10, 15, 3, 7}
    fmt.Println(twoNosAddUptoK(xs, 17))
}
0
Nikul