给定三个排序的整数数组A [] , B []和C [] ,任务是找到三个整数,每个数组中的一个整数,使它们求和成给定的目标值X。根据是否存在该三元组,打印“是”或“否” 。
例子:
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
方法:我们已经在本文中讨论了基于哈希的方法,该方法占用O(N)额外的空间。
在本文中,我们将使用节省空间O(1)的节省空间的方法来解决此问题。这个想法是使用两个指针技术。
我们将遍历所有数组中的最小数组,对于每个索引i ,我们将在较大的两个数组上使用双指针,以找到总和等于X – A [i]的一对(假设A []在三个arias中的长度)。
现在,在较大的两个数组上使用两个指针的背后的想法是什么?我们将通过一个示例来尝试理解相同的内容。
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.
算法:
- 按长度的增加顺序对数组进行排序。
- 假设排序后的最小数组是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。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
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
Yes
时间复杂度: O(min(len(A),len(B),len(C))* max(len(A),len(B),len(C)))