Найдите три элемента из данных трех массивов, сумма которых равна X | Комплект 2

Опубликовано: 13 Января, 2022

Для трех отсортированных целочисленных массивов A [] , B [] и C [] задача состоит в том, чтобы найти три целых числа, по одному из каждого массива, которые в сумме дают заданное целевое значение X. Выведите Yes или No в зависимости от того, существует такая тройка или нет.
Примеры:

Input: A[] = {2}, B[] = {1, 6, 7}, C[] = {4, 5}, X = 12 
Output: Yes 
A[0] + B[1] + C[0] = 2 + 6 + 4 = 12
Input: A[] = {2}, B[] = {1, 6, 7}, C[] = {4, 5}, X = 14 
Output: Yes 
A[0] + B[2] + C[1] = 2 + 7 + 5 = 14 
 

Рекомендуется: сначала попробуйте свой подход в {IDE}, прежде чем переходить к решению.

Подход: в этой статье мы уже обсуждали подход на основе хеширования, который требует O (N) дополнительного места.
В этой статье мы решим эту проблему, используя метод экономии места, который требует O (1) дополнительного места. Идея заключается в использовании техники двух указателей.
Мы будем перебирать наименьший из всех массивов, и для каждого индекса i мы будем использовать два указателя на двух больших массивах, чтобы найти пару с суммой, равной X - A [i] (предполагая, что A [] является наименьшим из длина среди трех аррий).
Теперь, какова идея использования двух указателей на двух больших массивах? Попробуем понять то же самое на примере.

Let’s assume 
len(A) = 100000 
len(B) = 10000 
len(C) = 10
Case 1: Applying two pointer on larger two arrays 
Number of iterations will be of order = len(C) * (len(A) + len(B)) = 10 * (110000) = 1100000
Case 2: Applying two pointer on smaller two arrays 
Number of iterations will be of order = len(A) * (len(B) + len(C)) = 100000 * (10010) = 1001000000
Case 3: Applying two pointer on smallest and largest array 
Number of iterations will be of order = len(B) * (len(A) + len(C)) = 10000 * (100000 + 10) = 1000100000
As we can see, Case 1 is the most optimal for this example and it can be easily proved that its most optimal in general as well. 
 

Алгоритм:

  1. Отсортируйте массивы в порядке возрастания их длины.
  2. Скажем, самый маленький массив после сортировки - это A []. Затем выполните итерацию по всем элементам A [] и для каждого индекса «i» примените два указателя к двум другим массивам. Мы поместим указатель в начало массива B [] и указатель на конец массива C []. Назовем указатель j и k соответственно.
    • Если B [j] + C [k] = X - A [i], мы нашли совпадение.
    • Если B [j] + C [k] меньше, чем X - A [i], мы увеличиваем значение 'j' на 1.
    • Если B [j] + C [k] больше, чем X - A [i], мы уменьшаем значение k на 1.

Below is the implementation of the above approach: 
 

C++

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that returns true if there
// exists a triplet with sum x
bool existsTriplet(int a[], int b[],
                   int c[], int x, int l1,
                   int l2, int l3)
{
    // Sorting arrays such that a[]
    // represents smallest array
    if (l2 <= l1 and l2 <= l3)
        swap(l2, l1), swap(a, b);
    else if (l3 <= l1 and l3 <= l2)
        swap(l3, l1), swap(a, c);
 
    // Iterating the smallest array
    for (int i = 0; i < l1; i++) {
 
        // Two pointers on second and third array
        int j = 0, k = l3 - 1;
        while (j < l2 and k >= 0) {
 
            // If a valid triplet is found
            if (a[i] + b[j] + c[k] == x)
                return true;
            if (a[i] + b[j] + c[k] < x)
                j++;
            else
                k--;
        }
    }
 
    return false;
}
 
// Driver code
int main()
{
    int a[] = { 2, 7, 8, 10, 15 };
    int b[] = { 1, 6, 7, 8 };
    int c[] = { 4, 5, 5 };
    int l1 = sizeof(a) / sizeof(int);
    int l2 = sizeof(b) / sizeof(int);
    int l3 = sizeof(c) / sizeof(int);
 
    int x = 14;
 
    if (existsTriplet(a, b, c, x, l1, l2, l3))
        cout << "Yes";
    else
        cout << "No";
 
    return 0;
}

Java

// Java implementation of the approach
class GFG
{
 
// Function that returns true if there
// exists a triplet with sum x
static boolean existsTriplet(int a[], int b[],
                      int c[], int x, int l1,
                              int l2, int l3)
{
    // Sorting arrays such that a[]
    // represents smallest array
    if (l2 <= l1 && l2 <= l3)
    {
        swap(l2, l1);
        swap(a, b);
    }
    else if (l3 <= l1 && l3 <= l2)
    {
        swap(l3, l1);
        swap(a, c);
    }
 
    // Iterating the smallest array
    for (int i = 0; i < l1; i++)
    {
 
        // Two pointers on second and third array
        int j = 0, k = l3 - 1;
        while (j < l2 && k >= 0)
        {
 
            // If a valid triplet is found
            if (a[i] + b[j] + c[k] == x)
                return true;
            if (a[i] + b[j] + c[k] < x)
                j++;
            else
                k--;
        }
    }
    return false;
}
 
private static void swap(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}
 
private static void swap(int []x, int []y)
{
    int []temp = x;
    x = y;
    y = temp;
}
 
// Driver code
public static void main(String[] args)
{
    int a[] = { 2, 7, 8, 10, 15 };
    int b[] = { 1, 6, 7, 8 };
    int c[] = { 4, 5, 5 };
    int l1 = a.length;
    int l2 = b.length;
    int l3 = c.length;
 
    int x = 14;
 
    if (existsTriplet(a, b, c, x, l1, l2, l3))
        System.out.println("Yes");
    else
        System.out.println("No");
}
}
 
// This code is contributed by Rajput-Ji

Python3

# Function that returns True if there
# exists a triplet with sum x
def existsTriplet(a, b,c, x, l1,l2, l3):
     
    # Sorting arrays such that a
    # represents smallest array
    if (l2 <= l1 and l2 <= l3):
        l1, l2 = l2,l1
        a, b = b,a
    elif (l3 <= l1 and l3 <= l2):
        l1, l3 = l3,l1
        a, c = c,a
 
    # Iterating the smallest array
    for i in range(l1):
 
        # Two pointers on second and third array
        j = 0
        k = l3 - 1
        while (j < l2 and k >= 0):
 
            # If a valid triplet is found
            if (a[i] + b[j] + c[k] == x):
                return True
            if (a[i] + b[j] + c[k] < x):
                j += 1
            else:
                k -= 1
 
    return False
 
# Driver code
a = [ 2, 7, 8, 10, 15 ]
b = [ 1, 6, 7, 8 ]
c = [ 4, 5, 5 ]
l1 = len(a)
l2 = len(b)
l3 = len(c)
 
x = 14
 
if (existsTriplet(a, b, c, x, l1, l2, l3)):
    print("Yes")
else:
    print("No")
 
# This code is contributed by mohit kumar 29

C#

// C# implementation of the approach
using System;
 
class GFG
{
 
// Function that returns true if there
// exists a triplet with sum x
static bool existsTriplet(int []a, int []b,
                          int []c, int x, int l1,
                          int l2, int l3)
{
    // Sorting arrays such that a[]
    // represents smallest array
    if (l2 <= l1 && l2 <= l3)
    {
        swap(l2, l1);
        swap(a, b);
    }
    else if (l3 <= l1 && l3 <= l2)
    {
        swap(l3, l1);
        swap(a, c);
    }
 
    // Iterating the smallest array
    for (int i = 0; i < l1; i++)
    {
 
        // Two pointers on second and third array
        int j = 0, k = l3 - 1;
        while (j < l2 && k >= 0)
        {
 
            // If a valid triplet is found
            if (a[i] + b[j] + c[k] == x)
                return true;
            if (a[i] + b[j] + c[k] < x)
                j++;
            else
                k--;
        }
    }
    return false;
}
 
private static void swap(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}
 
private static void swap(int []x, int []y)
{
    int []temp = x;
    x = y;
    y = temp;
}
 
// Driver code
public static void Main(String[] args)
{
    int []a = { 2, 7, 8, 10, 15 };
    int []b = { 1, 6, 7, 8 };
    int []c = { 4, 5, 5 };
    int l1 = a.Length;
    int l2 = b.Length;
    int l3 = c.Length;
 
    int x = 14;
 
    if (existsTriplet(a, b, c, x, l1, l2, l3))
        Console.WriteLine("Yes");
    else
        Console.WriteLine("No");
}
}
 
// This code is contributed by Rajput-Ji

Javascript

<script>
 
// JavaScript implementation of the approach
 
// Function that returns true if there
// exists a triplet with sum x
function existsTriplet(a, b, c, x, l1,
                    l2, l3)
{
    // Sorting arrays such that a[]
    // represents smallest array
    if (l2 <= l1 && l2 <= l3)
    {
        temp = l1; l1 = l2; l2 = temp;
        temp = a; a = b; b = temp;
    }
         
    else if (l3 <= l1 && l3 <= l2)
    {
        temp = l1; l1 = l3; l3 = temp;
        temp = a; a = c; c = temp;
    }
    // Iterating the smallest array
    for (var i = 0; i < l1; i++) {
 
        // Two pointers on second and third array
        var j = 0, k = l3 - 1;
        while (j < l2 && k >= 0) {
 
            // If a valid triplet is found
            if (a[i] + b[j] + c[k] == x)
                return true;
            if (a[i] + b[j] + c[k] < x)
                j++;
            else
                k--;
        }
    }
 
    return false;
}
 
// Driver code
var a = [ 2, 7, 8, 10, 15 ];
var b = [ 1, 6, 7, 8 ];
var c = [ 4, 5, 5 ];
var l1 = a.length;
var l2 = b.length;
var l3 = c.length;
var x = 14;
if (existsTriplet(a, b, c, x, l1, l2, l3))
    document.write("Yes");
else
    document.write("No");
 
</script>
Output: 
Yes

 

Сложность времени: O (min (len (A), len (B), len (C)) * max (len (A), len (B), len (C)))

Вниманию читателя! Не прекращайте учиться сейчас. Освойте все важные концепции DSA с помощью самостоятельного курса DSA по приемлемой для студентов цене и будьте готовы к работе в отрасли. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .

Если вы хотите посещать живые занятия с отраслевыми экспертами, пожалуйста, обращайтесь к Geeks Classes Live и Geeks Classes Live USA.