给定一个数组和一个总和值,找出该数组中所有可能的唯一三元组,其总和等于给定的总和值。如果无法从数组中形成这样的三元组,则打印“无法形成三元组”,否则打印所有唯一的三元组。例如,如果给定的数组是 {12, 3, 6, 1, 6, 9} 并且给定的总和是 24,那么唯一的三元组是 (3, 9, 12) 和 (6, 6, 12) 其总和是 24。
例子:
Input : array = {12, 3, 6, 1, 6, 9} sum = 24
Output : [[3, 9, 12], [6, 6, 12]]
Input : array = {-2, 0, 1, 1, 2} sum = 0
Output : [[-2, 0, 2], [-2, 1, 1]]
Input : array = {-2, 0, 1, 1, 2} sum = 10
Output : No triplets can be formed
方法一
在上一篇文章中,我们讨论了是否可以从数组中形成三元组。
在这里,我们需要打印总和为给定值的所有独特的三元组
- 对输入数组进行排序。
- 从数组 i、j 和 k 中找到三个索引,其中 A[i]+A[j]+A[k] = 给定的总和值。
- 将第一个元素固定为 A[i] 并从 0 迭代 i 到数组大小 – 2。
- 对于 i 的每次迭代,取 j 为剩余元素中第一个元素的索引,k 为最后一个元素的索引。
- 检查三元组组合 A[i]+A[j]+A[k] = 给定的总和值。
- 如果获得三元组(即 A[i]+A[j]+A[k] = 给定的总和值)
- 将 TreeSet 中的所有三元组以“:”分隔值相加得到唯一的三元组。
- 增加第二个值索引
- 递减第三个值索引。
- 重复步骤 4 和 5 直到 j < k
- 否则,如果 A[i]+A[j]+A[k] < 给定和值,则增加第二个值索引
否则,如果 A[i]+A[j]+A[k] > 给定和值,则递减第三个值索引
下面是上述想法的实现:
C++
// C++ program to find unique triplets
// that sum up to a given value.
#include
using namespace std;
// Structure to define a triplet.
struct triplet
{
int first, second, third;
};
// Function to find unique triplets that
// sum up to a given value.
int findTriplets(int nums[], int n, int sum)
{
int i, j, k;
// Vector to store all unique triplets.
vector triplets;
// Set to store already found triplets
// to avoid duplication.
unordered_set uniqTriplets;
// Variable used to hold triplet
// converted to string form.
string temp;
// Variable used to store current
// triplet which is stored in vector
// if it is unique.
triplet newTriplet;
// Sort the input array.
sort(nums, nums + n);
// Iterate over the array from the
// start and consider it as the
// first element.
for (i = 0; i < n - 2; i++)
{
// index of the first element in
// the remaining elements.
j = i + 1;
// index of the last element.
k = n - 1;
while (j < k) {
// If sum of triplet is equal to
// given value, then check if
// this triplet is unique or not.
// To check uniqueness, convert
// triplet to string form and
// then check if this string is
// present in set or not. If
// triplet is unique, then store
// it in vector.
if (nums[i] + nums[j] + nums[k] == sum)
{
temp = to_string(nums[i]) + " : "
+ to_string(nums[j]) + " : "
+ to_string(nums[k]);
if (uniqTriplets.find(temp)
== uniqTriplets.end()) {
uniqTriplets.insert(temp);
newTriplet.first = nums[i];
newTriplet.second = nums[j];
newTriplet.third = nums[k];
triplets.push_back(newTriplet);
}
// Increment the first index
// and decrement the last
// index of remaining elements.
j++;
k--;
}
// If sum is greater than given
// value then to reduce sum
// decrement the last index.
else if (nums[i] + nums[j] + nums[k] > sum)
k--;
// If sum is less than given value
// then to increase sum increment
// the first index of remaining
// elements.
else
j++;
}
}
// If no unique triplet is found, then
// return 0.
if (triplets.size() == 0)
return 0;
// Print all unique triplets stored in
// vector.
for (i = 0; i < triplets.size(); i++) {
cout << "[" << triplets[i].first << ", "
<< triplets[i].second << ", "
<< triplets[i].third << "], ";
}
}
// Driver Code
int main()
{
int nums[] = { 12, 3, 6, 1, 6, 9 };
int n = sizeof(nums) / sizeof(nums[0]);
int sum = 24;
// Function call
if (!findTriplets(nums, n, sum))
cout << "No triplets can be formed.";
return 0;
}
// This code is contributed by NIKHIL JINDAL.
Java
// Java program to find all triplets with given sum
import java.util.*;
public class triplets {
// returns all triplets whose sum is
// equal to sum value
public static List >
findTriplets(int[] nums, int sum)
{
/* Sort the elements */
Arrays.sort(nums);
List > pair
= new ArrayList<>();
TreeSet set
= new TreeSet();
List triplets
= new ArrayList<>();
/* Iterate over the array from the start
and consider it as the first element*/
for (int i = 0;
i < nums.length - 2;
i++) {
// index of the first element in the
// remaining elements
int j = i + 1;
// index of the last element
int k = nums.length - 1;
while (j < k) {
if (nums[i] + nums[j]
+ nums[k] == sum) {
String str
= nums[i] + ":" + nums[j]
+ ":" + nums[k];
if (!set.contains(str))
{
// To check for the unique triplet
triplets.add(nums[i]);
triplets.add(nums[j]);
triplets.add(nums[k]);
pair.add(triplets);
triplets = new ArrayList<>();
set.add(str);
}
// increment the second value index
j++;
// decrement the third value index
k--;
}
else if (nums[i]
+ nums[j]
+ nums[k] < sum)
j++;
else
k--;
}
}
return pair;
}
// Driver code
public static void main(String[] args)
{
int[] nums = { 12, 3, 6, 1, 6, 9 };
int sum = 24;
List > triplets
= findTriplets(nums, sum);
// Function call
if (!triplets.isEmpty()) {
System.out.println(triplets);
}
else {
System.out.println("No triplets can be formed");
}
}
}
Python3
# Python program to find unique triplets
# that sum up to a given value.
# Function to find unique triplets that
# sum up to a given value.
def findTriplets(nums, n, Sum):
i = 0
j = 0
k = 0
# list to store all unique triplets.
triplet = []
# list to store already found triplets
# to avoid duplication.
uniqTriplets = []
# Variable used to hold triplet
# converted to string form.
temp = ""
# Variable used to store current
# triplet which is stored in vector
# if it is unique.
newTriplet = [0, 0, 0]
# Sort the input array.
nums.sort()
# Iterate over the array from the
# start and consider it as the
# first element.
for i in range(n - 2):
# index of the first element in
# the remaining elements.
j = i + 1
# index of the last element.
k = n - 1
while(j < k):
# If sum of triplet is equal to
# given value, then check if
# this triplet is unique or not.
# To check uniqueness, convert
# triplet to string form and
# then check if this string is
# present in set or not. If
# triplet is unique, then store
# it in list.
if(nums[i] + nums[j] + nums[k] == Sum):
temp = str(nums[i]) + ":" + str(nums[j]) + ":" + str(nums[k])
if temp not in uniqTriplets:
uniqTriplets.append(temp)
newTriplet[0] = nums[i]
newTriplet[1] = nums[j]
newTriplet[2] = nums[k]
triplet.append(newTriplet)
newTriplet = [0, 0, 0]
# Increment the first index
# and decrement the last
# index of remaining elements.
j += 1
k -= 1
# If sum is greater than given
# value then to reduce sum
# decrement the last index.
elif(nums[i] + nums[j] + nums[k] > Sum):
k -= 1
# If sum is less than given value
# then to increase sum increment
# the first index of remaining
# elements.
else:
j += 1
# If no unique triplet is found, then
# return 0.
if(len(triplet) == 0):
return 0
# Print all unique triplets stored in
# list.
for i in range(len(triplet)):
print(triplet[i], end = ", ")
return 1
# Driver Code
nums = [12, 3, 6, 1, 6, 9]
n = len(nums)
Sum = 24
# Function call
if(not findTriplets(nums, n, Sum)):
print("No triplets can be formed.")
# This code is contributed by rag2127
C#
// C# program to find all triplets with given sum
using System;
using System.Collections.Generic;
class GFG {
// returns all triplets whose sum is
// equal to sum value
public static List>
findTriplets(int[] nums,int sum)
{
/* Sort the elements */
Array.Sort(nums);
List > pair
= new List >();
SortedSet set
= new SortedSet();
List triplets
= new List();
/* Iterate over the array from the start and
consider it as the first element*/
for (int i = 0;
i < nums.Length - 2;
i++) {
// index of the first element in the
// remaining elements
int j = i + 1;
// index of the last element
int k = nums.Length - 1;
while (j < k) {
if (nums[i]
+ nums[j]
+ nums[k] == sum) {
String str
= nums[i] + ":" + nums[j]
+ ":" + nums[k];
if (!set.Contains(str))
{
// To check for the unique triplet
triplets.Add(nums[i]);
triplets.Add(nums[j]);
triplets.Add(nums[k]);
pair.Add(triplets);
triplets = new List();
set.Add(str);
}
j++; // increment the second value index
k--; // decrement the third value index
}
else if (nums[i]
+ nums[j]
+ nums[k] < sum)
j++;
else
k--;
}
}
return pair;
}
// Driver Code
public static void Main(String[] args)
{
int[] nums = { 12, 3, 6, 1, 6, 9 };
int sum = 24;
List > triplets
= findTriplets(nums, sum);
// Function call
if (triplets.Count != 0) {
Console.Write("[");
for (int i = 0; i < triplets.Count; i++)
{
List l = triplets[i];
Console.Write("[");
for (int j = 0; j < l.Count; j++)
{
Console.Write(l[j]);
if (l.Count != j + 1)
Console.Write(", ");
}
Console.Write("]");
if (triplets.Count != i + 1)
Console.Write(",");
}
Console.Write("]");
}
else
{
Console.WriteLine("No triplets can be formed");
}
}
}
// This code is contributed by 29AjayKumar
Javascript
C++
// C++ program to find all unique triplets
// without using any extra space.
#include
using namespace std;
// Function to all find unique triplets
// without using extra space
void findTriplets(int a[], int n, int sum)
{
int i;
// Sort the input array
sort(a, a + n);
// For handling the cases when no such
// triplets exits.
bool flag = false;
// Iterate over the array from start to n-2.
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
// Index of the first element in
// remaining range.
int start = i + 1;
// Index of the last element
int end = n - 1;
// Setting our new target
int target = sum - a[i];
while (start < end)
{
// Checking if current element
// is same as previous
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue;
}
// Checking if current element is
// same as previous
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue;
}
// If we found the triplets then print it
// and set the flag
if (target == a[start] + a[end])
{
cout << "[" << a[i]
<< "," << a[start]
<< "," << a[end] << "] ";
flag = true;
start++;
end--;
}
// If target is greater then
// increment the start index
else if (target > (a[start] + a[end]))
{
start++;
}
// If target is smaller than
// decrement the end index
else {
end--;
}
}
}
}
// If no such triplets found
if (flag == false) {
cout << "No Such Triplets Exist"
<< "\n";
}
}
// Driver code
int main()
{
int a[] = { 12, 3, 6, 1, 6, 9 };
int n = sizeof(a) / sizeof(a[0]);
int sum = 24;
// Function call
findTriplets(a, n, sum);
return 0;
}
// This code is contributed by Rohit
Java
// Java program to find all unique triplets
// without using any extra space.
import java.util.*;
public class Main
{
// Function to all find unique triplets
// without using extra space
public static void findTriplets(int a[], int n, int sum)
{
int i;
// Sort the input array
Arrays.sort(a);
// For handling the cases when no such
// triplets exits.
boolean flag = false;
// Iterate over the array from start to n-2.
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
// Index of the first element in
// remaining range.
int start = i + 1;
// Index of the last element
int end = n - 1;
// Setting our new target
int target = sum - a[i];
while (start < end)
{
// Checking if current element
// is same as previous
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue;
}
// Checking if current element is
// same as previous
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue;
}
// If we found the triplets then print it
// and set the flag
if (target == a[start] + a[end])
{
System.out.print("[" + a[i]
+ "," + a[start]
+ "," + a[end] + "] ");
flag = true;
start++;
end--;
}
// If target is greater then
// increment the start index
else if (target > (a[start] + a[end]))
{
start++;
}
// If target is smaller than
// decrement the end index
else {
end--;
}
}
}
}
// If no such triplets found
if (flag == false) {
System.out.print("No Such Triplets Exist");
}
}
public static void main(String[] args) {
int a[] = { 12, 3, 6, 1, 6, 9 };
int n = a.length;
int sum = 24;
// Function call
findTriplets(a, n, sum);
}
}
// This code is contributed by divyeshrabadiya07
Python3
# Python3 program to find all
# unique triplets without using
# any extra space.
# Function to all find unique
# triplets without using extra
# space
def findTriplets(a, n, sum):
# Sort the input array
a.sort()
# For handling the cases
# when no such triplets exits.
flag = False
# Iterate over the array from
# start to n-2.
for i in range(n - 2):
if (i == 0 or
a[i] > a[i - 1]):
# Index of the first
# element in remaining
# range.
start = i + 1
# Index of the last
# element
end = n - 1
# Setting our new target
target = sum - a[i]
while (start < end):
# Checking if current element
# is same as previous
if (start > i + 1 and
a[start] == a[start - 1]):
start += 1
continue
# Checking if current
# element is same as
# previous
if (end < n - 1 and
a[end] == a[end + 1]):
end -= 1
continue
# If we found the triplets
# then print it and set the
# flag
if (target == a[start] + a[end]):
print("[", a[i], ",",
a[start], ",",
a[end], "]",
end = " ")
flag = True
start += 1
end -= 1
# If target is greater then
# increment the start index
elif (target >
(a[start] + a[end])):
start += 1
# If target is smaller than
# decrement the end index
else:
end -= 1
# If no such triplets found
if (flag == False):
print("No Such Triplets Exist")
# Driver code
if __name__ == "__main__":
a = [12, 3, 6, 1, 6, 9]
n = len(a)
sum = 24
# Function call
findTriplets(a, n, sum)
# This code is contributed by Chitranayal
C#
// C# program to find all unique triplets
// without using any extra space.
using System;
using System.Collections.Generic;
class GFG {
// Function to all find unique triplets
// without using extra space
static void findTriplets(int[] a, int n, int sum)
{
int i;
// Sort the input array
Array.Sort(a);
// For handling the cases when no such
// triplets exits.
bool flag = false;
// Iterate over the array from start to n-2.
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
// Index of the first element in
// remaining range.
int start = i + 1;
// Index of the last element
int end = n - 1;
// Setting our new target
int target = sum - a[i];
while (start < end)
{
// Checking if current element
// is same as previous
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue;
}
// Checking if current element is
// same as previous
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue;
}
// If we found the triplets then print it
// and set the flag
if (target == a[start] + a[end])
{
Console.Write("[" + a[i]
+ "," + a[start]
+ "," + a[end] + "] ");
flag = true;
start++;
end--;
}
// If target is greater then
// increment the start index
else if (target > (a[start] + a[end]))
{
start++;
}
// If target is smaller than
// decrement the end index
else {
end--;
}
}
}
}
// If no such triplets found
if (flag == false) {
Console.WriteLine("No Such Triplets Exist");
}
}
static void Main() {
int[] a = { 12, 3, 6, 1, 6, 9 };
int n = a.Length;
int sum = 24;
// Function call
findTriplets(a, n, sum);
}
}
// This code is contributed by divyesh072019
Javascript
输出
[3, 9, 12], [6, 6, 12],
时间复杂度: O(n 2 )
空间复杂度:O(n)
方法二
在这种方法中,我们将看到另一种解决此问题的方法,该方法仅使用恒定量的空间。在此方法中,我们将检查当前元素是否与前一个元素相同,然后我们不会考虑它,只是简单地跳过该元素。通过使用它,我们将只能找到唯一的三元组。
算法
- 对输入数组进行排序。
- 对于第一个元素,从 0 到 n-2 迭代 i。
- 对于每次迭代,我们将有两个索引开始和结束,其中开始等于 i+1,结束等于 n-1。
- 现在我们将使用两种指针技术在从开始到结束的范围内寻找值为 sum-a[i] 的目标。
- 在这种情况下,我们将查找之前的元素,如果它们相同,那么我们将不会让它们找到所有唯一的重复项。
- 如果我们发现 target==a[start]+a[end] 那么我们将打印它并增加 start 并减少 end。
- 如果 target>a[start]+a[end] 那么我们将增加 start。
- 否则我们将递减结束
下面是上述想法的实现:
C++
// C++ program to find all unique triplets
// without using any extra space.
#include
using namespace std;
// Function to all find unique triplets
// without using extra space
void findTriplets(int a[], int n, int sum)
{
int i;
// Sort the input array
sort(a, a + n);
// For handling the cases when no such
// triplets exits.
bool flag = false;
// Iterate over the array from start to n-2.
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
// Index of the first element in
// remaining range.
int start = i + 1;
// Index of the last element
int end = n - 1;
// Setting our new target
int target = sum - a[i];
while (start < end)
{
// Checking if current element
// is same as previous
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue;
}
// Checking if current element is
// same as previous
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue;
}
// If we found the triplets then print it
// and set the flag
if (target == a[start] + a[end])
{
cout << "[" << a[i]
<< "," << a[start]
<< "," << a[end] << "] ";
flag = true;
start++;
end--;
}
// If target is greater then
// increment the start index
else if (target > (a[start] + a[end]))
{
start++;
}
// If target is smaller than
// decrement the end index
else {
end--;
}
}
}
}
// If no such triplets found
if (flag == false) {
cout << "No Such Triplets Exist"
<< "\n";
}
}
// Driver code
int main()
{
int a[] = { 12, 3, 6, 1, 6, 9 };
int n = sizeof(a) / sizeof(a[0]);
int sum = 24;
// Function call
findTriplets(a, n, sum);
return 0;
}
// This code is contributed by Rohit
Java
// Java program to find all unique triplets
// without using any extra space.
import java.util.*;
public class Main
{
// Function to all find unique triplets
// without using extra space
public static void findTriplets(int a[], int n, int sum)
{
int i;
// Sort the input array
Arrays.sort(a);
// For handling the cases when no such
// triplets exits.
boolean flag = false;
// Iterate over the array from start to n-2.
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
// Index of the first element in
// remaining range.
int start = i + 1;
// Index of the last element
int end = n - 1;
// Setting our new target
int target = sum - a[i];
while (start < end)
{
// Checking if current element
// is same as previous
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue;
}
// Checking if current element is
// same as previous
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue;
}
// If we found the triplets then print it
// and set the flag
if (target == a[start] + a[end])
{
System.out.print("[" + a[i]
+ "," + a[start]
+ "," + a[end] + "] ");
flag = true;
start++;
end--;
}
// If target is greater then
// increment the start index
else if (target > (a[start] + a[end]))
{
start++;
}
// If target is smaller than
// decrement the end index
else {
end--;
}
}
}
}
// If no such triplets found
if (flag == false) {
System.out.print("No Such Triplets Exist");
}
}
public static void main(String[] args) {
int a[] = { 12, 3, 6, 1, 6, 9 };
int n = a.length;
int sum = 24;
// Function call
findTriplets(a, n, sum);
}
}
// This code is contributed by divyeshrabadiya07
蟒蛇3
# Python3 program to find all
# unique triplets without using
# any extra space.
# Function to all find unique
# triplets without using extra
# space
def findTriplets(a, n, sum):
# Sort the input array
a.sort()
# For handling the cases
# when no such triplets exits.
flag = False
# Iterate over the array from
# start to n-2.
for i in range(n - 2):
if (i == 0 or
a[i] > a[i - 1]):
# Index of the first
# element in remaining
# range.
start = i + 1
# Index of the last
# element
end = n - 1
# Setting our new target
target = sum - a[i]
while (start < end):
# Checking if current element
# is same as previous
if (start > i + 1 and
a[start] == a[start - 1]):
start += 1
continue
# Checking if current
# element is same as
# previous
if (end < n - 1 and
a[end] == a[end + 1]):
end -= 1
continue
# If we found the triplets
# then print it and set the
# flag
if (target == a[start] + a[end]):
print("[", a[i], ",",
a[start], ",",
a[end], "]",
end = " ")
flag = True
start += 1
end -= 1
# If target is greater then
# increment the start index
elif (target >
(a[start] + a[end])):
start += 1
# If target is smaller than
# decrement the end index
else:
end -= 1
# If no such triplets found
if (flag == False):
print("No Such Triplets Exist")
# Driver code
if __name__ == "__main__":
a = [12, 3, 6, 1, 6, 9]
n = len(a)
sum = 24
# Function call
findTriplets(a, n, sum)
# This code is contributed by Chitranayal
C#
// C# program to find all unique triplets
// without using any extra space.
using System;
using System.Collections.Generic;
class GFG {
// Function to all find unique triplets
// without using extra space
static void findTriplets(int[] a, int n, int sum)
{
int i;
// Sort the input array
Array.Sort(a);
// For handling the cases when no such
// triplets exits.
bool flag = false;
// Iterate over the array from start to n-2.
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
// Index of the first element in
// remaining range.
int start = i + 1;
// Index of the last element
int end = n - 1;
// Setting our new target
int target = sum - a[i];
while (start < end)
{
// Checking if current element
// is same as previous
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue;
}
// Checking if current element is
// same as previous
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue;
}
// If we found the triplets then print it
// and set the flag
if (target == a[start] + a[end])
{
Console.Write("[" + a[i]
+ "," + a[start]
+ "," + a[end] + "] ");
flag = true;
start++;
end--;
}
// If target is greater then
// increment the start index
else if (target > (a[start] + a[end]))
{
start++;
}
// If target is smaller than
// decrement the end index
else {
end--;
}
}
}
}
// If no such triplets found
if (flag == false) {
Console.WriteLine("No Such Triplets Exist");
}
}
static void Main() {
int[] a = { 12, 3, 6, 1, 6, 9 };
int n = a.Length;
int sum = 24;
// Function call
findTriplets(a, n, sum);
}
}
// This code is contributed by divyesh072019
Javascript
输出
[3,9,12] [6,6,12]
复杂度分析:
- 时间复杂度: O(n 2 )。
由于需要两个嵌套循环,所以时间复杂度为 O(n 2 )。 - 辅助空间: O(1)。
因为我们不需要额外的空间来解决这个问题。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。