web-dev-qa-db-ja.com

数値のリストと数値kを指定すると、リストの2つの数値が合計してkになるかどうかを返します

この質問は、Googleプログラミングインタビューで尋ねられました。同じために2つのアプローチを考えました:

  1. 長さのすべてのサブシーケンスを見つけます。そうしながら、2つの要素の合計を計算し、kと等しいかどうかを確認します。 「はい」の場合は「はい」を、そうでない場合は検索を続けます。これはブルートフォースアプローチです。

  2. 配列を降順で並べ替えます。次に、配列の右端から走査を開始します。ソートされた配列{3,5,7,10}があり、合計を17にしたいとします。要素10から始めます。index= 3で、インデックスを 'j'で示しましょう。次に、現在の要素を含めて、required_sum = sum-current_elementを計算します。その後、array [0-(j-1)]でバイナリまたはターナリ検索を実行して、値がrequired_sumに等しい要素があるかどうかを確認できます。そのような要素が見つかった場合、合計が与えられた合計である長さ2のサブシーケンスが見つかったため、ブレークできます。そのような要素が見つからない場合は、jのインデックスを減らし、長さ=長さ-1の結果のサブ配列に対して上記の手順を繰り返します。つまり、この場合はインデックス3の要素を除外します。

ここでは、配列は正の整数だけでなく負の整数も持つことができると考えました。

これよりも良い解決策を提案できますか?多分DPソリューション?時間の複雑さをさらに軽減できるソリューション。

19
Jhanak Didwania

この問題は、O(N)時間と空間の複雑さのセットの助けを借りて簡単に解決できます。最初に配列のすべての要素をセットに追加し、次に配列の各要素をトラバースし、K-ar [ i]がセットに存在するかどうか。

Javaの複雑さを持つ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");
21
NIKUNJ KHOKHAR

以下は、配列のソートに使用されるアルゴリズムと同じ時間の複雑さを持つJava実装です。これは、番号を調べるたびに一致するパートナーを配列全体で検索する必要がないため、2番目のアイデアよりも高速であることに注意してください。

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

帰納法による証明: a [0、n]を長さn + 1およびp =(p1、p2)の配列とします。p1、p2は整数で、p1 <= p2(w.l.o.g.)です。 a [0、n]にp1とp2が含まれると仮定します。そうでない場合、アルゴリズムは明らかに正しいです。

基本ケース(i = 0、j = n): a [0、-1]にはp1が含まれず、a [n、n + 1]にはp2が含まれません。

仮説: a [0、i-1]にはa [i]は含まれず、a [j + 1、n]にはp2が含まれません。

ステップケース(i to i + 1またはj to j-1):

  1. P1 = a [i]と仮定します。次に、p1 + a [j] <p1 + p2なので、インデックスjを増やす必要があります。しかし、仮説から、a [j + 1、n-1]にはp2が含まれていないことがわかります。矛盾。その結果、p1!= a [i]になります。
  2. jからj-1も同様です。

各反復で、a [0、i-1]とa [j + 1、n]にはp1とp2が含まれないため、a [i、j]にはp1とp2が含まれます。最終的にa [i] = p1およびa [j] = p2になり、アルゴリズムはtrueを返します。

17
Niki

ペアカウントを検索する場合は、

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

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

print(counter//2)
6
Ilkin

これは、Java時間の複雑さとO(n)スペースを使用したO(n)実装です。アイデアは、すべての配列要素w.r.tターゲットの補数を含むHashMapを持っています。補数が見つかった場合、合計がターゲットになる2つの配列要素があります。

 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

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

または

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

Scalaを使用して、O(n)の時間と空間の複雑さを伴う単一パスで。

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

解決策は、配列の1つのパスで見つけることができます。ハッシュセットを初期化し、配列の反復を開始します。配列内の現在の要素がセット内で見つかった場合はtrueを返し、そうでない場合はこの要素の補数(x-arr [i])をセットに追加します。配列の反復が返されずに終了した場合、合計がxに等しいペアが存在しないため、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;
 }

こちらが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++ソリューション:

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ソリューション:

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

C++で2つのソリューションを思いつきました。 1つは、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;}

ご想像のとおり、このソリューションでは、入力の値が大きいと時間がかかります。

2番目のソリューションは、O(N)の時間で実装できました。上記のソリューションと同様に、unordered_setを使用します。

#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

Pythonコード:

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

Pythonがあります。オン)。リストには重複した番号がない可能性があるため、ループ中に現在の要素を削除する必要があります。

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

これがCの実装です
並べ替えO(n2)時間とスペースの複雑さ。
問題を解決するために、再帰を介してO(n)時間と空間の複雑さでシングルパスを使用します。
/*数値のリストと数値kを指定すると、リストから任意の2つの数値を合計してkの天気を返します。たとえば、[10,15,3,7]とkが17の場合、10 + 7を返すと17ボーナスになります。 * /

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

出力

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

私の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

毎日のコーディング問題に対する私の答え

# 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

javaScriptのソリューション

この関数は2つのパラメーターを取り、リストの長さをループします。ループ内には、リスト内の他の番号に1つの数値を追加し、kと等しいかどうかをチェックする別のループがあります

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

Pythonの複雑さを持つO(N) 3.7のコードは次のとおりです。

            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

Python 3.7のO(N ^ 2)複雑度のベストケースコード:

            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実装:コードは、辞書を使用してO(n)複雑度で実行されます。 (desired_output-current_input)を辞書のキーとして保存します。そして、その番号が辞書に存在するかどうかを確認します。辞書での検索は、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

vavr ライブラリを使用すると、かなり簡潔に行うことができます。

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

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

0
Nifemi Sola-Ojo

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

Swiftソリューションは次のとおりです。

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#ソリューション:

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ソリューション

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

以下に、2つの非常に高速なPython実装を示します([1,2]および2の入力がfalseを返す必要がある場合に対応します。つまり、数字を2倍にすることはできません。 「任意の2つ」を指定します)。

最初の1つは、用語のリストをループし、目的の合計に達するまで、以前に見たすべての用語に各用語を追加します。

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

これは、用語のリストにある差に達するまで結果から各用語を減算します(a+b=c -> c-a=bというルールを使用)。 enumerateと奇数リストインデックスの使用は、この回答の最初の文ごとに現在の値を除外することです。

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

番号を自分自身に追加できる場合、2番目の実装は次のように簡略化できます。

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

Go Langで解決策を試しました。ただし、O(n ^ 2)時間を消費します。

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
user2877627