Cette question a été posée dans l'interview de programmation de Google. J'ai pensé à deux approches pour le même:
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.
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.
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");
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;
}
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;
}
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)
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)
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 )
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;
}
Solution Javascript:
function hasSumK(arr, k) {
hashMap = {};
for (let value of arr) {
if (hashMap[value]) { return true;} else { hashMap[k - value] = true };
}
return false;
}
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;
}
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.
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
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
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.
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))
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;
}
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))
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())
}
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;
}
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);
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;
}
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
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))
}