web-dev-qa-db-fra.com

Étant donné une liste de nombres et un nombre k, indique si deux nombres de la liste totalisent

Cette question a été posée dans l'interview de programmation de Google. J'ai pensé à deux approches pour le même:

  1. Trouvez toutes les sous-séquences de longueur. Ce faisant, calculez la somme et les deux éléments et vérifiez si elle est égale à k. Si oui, imprimez Oui, sinon continuez votre recherche. C'est une approche de force brute.

  2. Triez le tableau dans un ordre non décroissant. Puis commencez à parcourir le tableau à partir de son extrémité droite. Supposons que nous ayons le tableau trié, {3,5,7,10}, et que nous voulons que la somme soit égale à 17. Nous commencerons à partir de l'élément 10, index = 3, notons l'index avec 'j'. Incluez ensuite l'élément en cours et calculez required_sum = sum - current_element. Après cela, nous pouvons effectuer une recherche binaire ou ternaire dans le tableau [0- (j-1)] pour rechercher s'il existe un élément dont la valeur est égale à la somme requise. Si nous trouvons un tel élément, nous pouvons rompre car nous avons trouvé une sous-séquence de longueur 2 dont la somme est la somme donnée. Si nous ne trouvons aucun élément de ce type, diminuez l'indice de j et répétez les étapes susmentionnées pour le sous-tableau résultant de longueur = longueur-1, c'est-à-dire en excluant l'élément d'indice 3 dans ce cas. 

Ici, nous avons considéré que ce tableau pourrait avoir des entiers négatifs aussi bien que positifs.

Pouvez-vous suggérer une meilleure solution que celle-ci? Une solution de DP peut-être? Une solution qui peut réduire davantage sa complexité temporelle.

9
Jhanak Didwania

Cette question peut être facilement résolue à l’aide de set dans O(N) complexité dans le temps et dans l’espace. Ajoutez d’abord tous les éléments du tableau à set, puis parcourez chaque élément du tableau et vérifiez si K-ar [i] est présent dans le set ou non. 

Voici le code en Java avec la complexité O(N):

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

Voici une implémentation Java avec la même complexité temporelle que l'algorithme utilisé pour trier le tableau. Notez que ceci est plus rapide que votre seconde idée car nous n'avons pas besoin de rechercher le partenaire complet dans le tableau à chaque fois que nous examinons un nombre.

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

Ceci est une implémentation Java avec O(n) Complexité temporelle et O(n) espace. L'idée est d'avoir un HashMap qui contiendra des compléments de chaque élément de tableau w.r.t target. Si le complément est trouvé, nous avons 2 éléments de tableau qui totalisent la cible.

 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

si vous voulez trouver le nombre de paires,

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

Utilisation de Scala, en un seul passage avec O(n) complexité temporelle et spatiale.

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

La solution peut être trouvée en un seul passage du tableau. Initialisez un ensemble de hachage et commencez à itérer le tableau. Si l'élément en cours dans le tableau se trouve dans l'ensemble, retournez true, sinon ajoutez le complément de cet élément (x - arr [i]) à l'ensemble. Si l'itération de array se termine sans retourner, cela signifie qu'il n'y a pas de paire de ce type dont la somme est égale à x, donc retourne false.

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

Voici l'implémentation de 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

Solution C++: 

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

Solution Javascript:

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

Je suis venu avec deux solutions en C++. L'un était un type de force brute naïf qui était en temps O (n ^ 2).

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

Comme vous pouvez l'imaginer, cette solution prendra beaucoup de temps pour des valeurs d'entrée plus élevées.

Ma deuxième solution que j'ai pu mettre en œuvre en O(N) temps. Utiliser un unordered_set, un peu comme la solution ci-dessus.

#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

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

Voici Python. Sur). Nécessité de supprimer l'élément en cours lors de la mise en boucle car la liste pourrait ne pas contenir de numéros en double.

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

Voici une implémentation en C
Pour trier O (n2) complexité temporelle et spatiale.
Pour résoudre un problème Nous utilisons Passe unique avec O(n) complexité temporelle et spatiale via Récursion.
/* Soit une liste de nombres et un nombre k, deux des nombres de la liste retournent tous les chiffres de la liste. est 17 Bonus: Pouvez-vous faire en un seul passage? * /

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

SORTIE

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

Solution Python:

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))

Ou

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

Mon implémentation C #:

 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

Implémentation Python: Le code serait exécuté dans la complexité O(n) avec l'utilisation du dictionnaire. Nous stockerions la valeur désirée (output_input - current_input) dans le dictionnaire. Et ensuite, nous vérifierions si le numéro existe dans le dictionnaire ou non. La recherche dans un dictionnaire a une complexité moyenne égale à 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

J'ai implémenté avec Scala

  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

Voici une solution javascript:

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

Solution C #:

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

Voici deux implémentations très rapides de Python (qui tiennent compte du cas où les entrées de [1,2] et 2 devraient renvoyer false; autrement dit, vous ne pouvez pas doubler un nombre, car il spécifie "deux quelconques").

Cette première boucle parcourt la liste des termes et ajoute chaque terme à tous les termes précédemment vus jusqu'à ce qu'il atteigne la somme désirée.

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

Celui-ci soustrait chaque terme du résultat jusqu'à atteindre une différence figurant dans la liste des termes (en utilisant la règle a+b=c -> c-a=b). L'utilisation de enumerate et l'indexation de liste impaire servent à exclure la valeur actuelle, conformément à la première phrase de cette réponse.

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

Si vous autorisez l'ajout d'un nombre à lui-même, la seconde implémentation pourrait être simplifiée pour:

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

J'ai essayé la solution dans Go Lang. Cependant, il consomme O (n ^ 2) fois.

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