给定一个整数数组,找出数组中四个元素的任意组合,其和等于给定值X。
null
例如
Input: array = {10, 2, 3, 4, 5, 9, 7, 8} X = 23 Output: 3 5 7 8Sum of output is equal to 23, i.e. 3 + 5 + 7 + 8 = 23.Input: array = {1, 2, 3, 4, 5, 9, 7, 8} X = 16 Output: 1 3 5 7Sum of output is equal to 16, i.e. 1 + 3 + 5 + 7 = 16.
我们讨论了一个问题 O(n) 3. ) 算法 上一篇文章 关于这个话题。这个问题可以在短期内解决 O(n) 2. Logn) 借助辅助空间的时间。 多亏了尼米什提出了这种方法。以下是详细的过程。
方法1: 双指针算法。 方法: 将输入数组设为[]。
- 创建一个辅助数组aux[],并将所有可能对的总和存储在aux[]中。aux[]的大小将为n*(n-1)/2,其中n是A[]的大小。
- 对辅助数组aux[]进行排序。
- 现在问题简化为在aux[]中找到两个元素,其和等于X。我们可以使用本文的方法1高效地找到这两个元素。不过,有以下几点需要注意: aux[]的一个元素表示一个[]中的一对。在从aux[]中选取两个元素时,我们必须检查这两个元素是否有共同的[]元素。例如,如果A[1]和A[2]的第一个元素和,而第二个元素是A[2]和A[4]的和,那么aux[]的这两个元素并不代表输入数组A[]的四个不同元素。
以下是上述方法的实施情况:
C++
// C++ program to find 4 elements // with given sum #include <bits/stdc++.h> using namespace std; // The following structure is needed // to store pair sums in aux[] class pairSum { public : // index (int A[]) of first element in pair int first; // index of second element in pair int sec; // sum of the pair int sum; }; // Following function is needed // for library function qsort() int compare( const void * a, const void * b) { return ((*(pairSum*)a).sum - (*(pairSum*)b).sum); } // Function to check if two given pairs // have any common element or not bool noCommon(pairSum a, pairSum b) { if (a.first == b.first || a.first == b.sec || a.sec == b.first || a.sec == b.sec) return false ; return true ; } // The function finds four // elements with given sum X void findFourElements( int arr[], int n, int X) { int i, j; // Create an auxiliary array // to store all pair sums int size = (n * (n - 1)) / 2; pairSum aux[size]; // Generate all possible pairs // from A[] and store sums // of all possible pairs in aux[] int k = 0; for (i = 0; i < n - 1; i++) { for (j = i + 1; j < n; j++) { aux[k].sum = arr[i] + arr[j]; aux[k].first = i; aux[k].sec = j; k++; } } // Sort the aux[] array using // library function for sorting qsort (aux, size, sizeof (aux[0]), compare); // Now start two index variables // from two corners of array // and move them toward each other. i = 0; j = size - 1; while (i < size && j >= 0) { if ((aux[i].sum + aux[j].sum == X) && noCommon(aux[i], aux[j])) { cout << arr[aux[i].first] << ", " << arr[aux[i].sec] << ", " << arr[aux[j].first] << ", " << arr[aux[j].sec] << endl; return ; } else if (aux[i].sum + aux[j].sum < X) i++; else j--; } } // Driver code int main() { int arr[] = { 10, 20, 30, 40, 1, 2 }; int n = sizeof (arr) / sizeof (arr[0]); int X = 91; // Function Call findFourElements(arr, n, X); return 0; } // This is code is contributed by rathbhupendra |
C
// C program to find 4 elements // with given sum #include <stdio.h> #include <stdlib.h> // The following structure is // needed to store pair sums in aux[] struct pairSum { // index (int A[]) of first element in pair int first; // index of second element in pair int sec; // sum of the pair int sum; }; // Following function is needed // for library function qsort() int compare( const void * a, const void * b) { return ((*(pairSum*)a).sum - (*(pairSum*)b).sum); } // Function to check if two given // pairs have any common element or not bool noCommon( struct pairSum a, struct pairSum b) { if (a.first == b.first || a.first == b.sec || a.sec == b.first || a.sec == b.sec) return false ; return true ; } // The function finds four // elements with given sum X void findFourElements( int arr[], int n, int X) { int i, j; // Create an auxiliary array // to store all pair sums int size = (n * (n - 1)) / 2; struct pairSum aux[size]; // Generate all possible pairs // from A[] and store sums // of all possible pairs in aux[] int k = 0; for (i = 0; i < n - 1; i++) { for (j = i + 1; j < n; j++) { aux[k].sum = arr[i] + arr[j]; aux[k].first = i; aux[k].sec = j; k++; } } // Sort the aux[] array using // library function for sorting qsort (aux, size, sizeof (aux[0]), compare); // Now start two index variables // from two corners of array // and move them toward each other. i = 0; j = size - 1; while (i < size && j >= 0) { if ((aux[i].sum + aux[j].sum == X) && noCommon(aux[i], aux[j])) { printf ( "%d, %d, %d, %d" , arr[aux[i].first], arr[aux[i].sec], arr[aux[j].first], arr[aux[j].sec]); return ; } else if (aux[i].sum + aux[j].sum < X) i++; else j--; } } // Driver code int main() { int arr[] = { 10, 20, 30, 40, 1, 2 }; int n = sizeof (arr) / sizeof (arr[0]); int X = 91; // Function call findFourElements(arr, n, X); return 0; } |
C#
// C# program to find 4 elements // with given sum using System; class GFG{ // The following structure is needed // to store pair sums in aux[] class pairSum { // Index (int A[]) of first element in pair public int first; // Index of second element in pair public int sec; // Sum of the pair public int sum; } // Function to check if two given pairs // have any common element or not static bool noCommon(pairSum a, pairSum b) { if (a.first == b.first || a.first == b.sec || a.sec == b.first || a.sec == b.sec) return false ; return true ; } // Following function is needed for sorting // pairSum array static int compare(pairSum a, pairSum b) { return (a.sum - b.sum); } // The function finds four // elements with given sum X static void findFourElements( int [] myArr, int sum) { int i, j; int length = myArr.Length; // Create an auxiliary array to // store all pair sums int size = (length * (length - 1)) / 2; pairSum[] aux = new pairSum[size]; // Generate all possible pairs // from A[] and store sums // of all possible pairs in aux[] int k = 0; for (i = 0; i < length - 1; i++) { for (j = i + 1; j < length; j++) { aux[k] = new pairSum(); aux[k].sum = myArr[i] + myArr[j]; aux[k].first = i; aux[k].sec = j; k++; } } // Sort the aux[] array using // library function for sorting Array.Sort(aux, compare); // Now start two index variables // from two corners of array // and move them toward each other. i = 0; j = size - 1; while (i < size && j >= 0) { if ((aux[i].sum + aux[j].sum == sum) && noCommon(aux[i], aux[j])) { string output = myArr[aux[i].first] + ", " + myArr[aux[i].sec] + ", " + myArr[aux[j].first] + ", " + myArr[aux[j].sec]; Console.WriteLine(output); return ; } else if (aux[i].sum + aux[j].sum < sum) i++; else j--; } } // Driver code static public void Main() { int [] arr = { 10, 20, 30, 40, 1, 2 }; int X = 91; // Function call findFourElements(arr, X); } } // This code is contributed by srastog |
输出
20, 1, 30, 40
请注意,上面的代码只打印四分之一。如果我们删除return语句并添加语句“i++;j–;”,然后再打印五次相同的四倍。代码可以修改为只打印一次所有四个字符。它一直保持这种方式,以保持它的简单。 复杂性分析:
- 时间复杂性: O(n^2Logn)。 第一步需要O(n^2)时间。第二步是对大小为O(n^2)的数组进行排序。可以使用合并排序、堆排序或任何其他O(nLogn)算法在O(n^2Logn)时间内完成排序。第三步需要O(n^2)时间。所以总体复杂度是O(n^2Logn)。
- 辅助空间: O(n^2)。 辅助数组的大小为O(n^2)。在这种方法中,辅助阵列的大尺寸可能是一个问题。
方法2: 基于哈希的解决方案[O(n 2. )]
方法:
- 将所有对的总和存储在哈希表中
- 再次遍历所有对并搜索 X–(当前对总和) 在哈希表中。
- 如果找到具有所需和的对,则确保所有元素都是不同的数组元素,并且一个元素不会被多次考虑。
下图是上述方法的试运行:
以下是上述方法的实施情况:
C++
// A hashing based CPP program // to find if there are // four elements with given sum. #include <bits/stdc++.h> using namespace std; // The function finds four // elements with given sum X void findFourElements( int arr[], int n, int X) { // Store sums of all pairs // in a hash table unordered_map< int , pair< int , int > > mp; for ( int i = 0; i < n - 1; i++) for ( int j = i + 1; j < n; j++) mp[arr[i] + arr[j]] = { i, j }; // Traverse through all pairs and search // for X - (current pair sum). for ( int i = 0; i < n - 1; i++) { for ( int j = i + 1; j < n; j++) { int sum = arr[i] + arr[j]; // If X - sum is present in hash table, if (mp.find(X - sum) != mp.end()) { // Making sure that all elements are // distinct array elements and an element // is not considered more than once. pair< int , int > p = mp[X - sum]; if (p.first != i && p.first != j && p.second != i && p.second != j) { cout << arr[i] << ", " << arr[j] << ", " << arr[p.first] << ", " << arr[p.second]; return ; } } } } } // Driver code int main() { int arr[] = { 10, 20, 30, 40, 1, 2 }; int n = sizeof (arr) / sizeof (arr[0]); int X = 91; // Function call findFourElements(arr, n, X); return 0; } |
JAVA
// A hashing based Java program to find // if there are four elements with given sum. import java.util.HashMap; class GFG { static class pair { int first, second; public pair( int first, int second) { this .first = first; this .second = second; } } // The function finds four elements // with given sum X static void findFourElements( int arr[], int n, int X) { // Store sums of all pairs in a hash table HashMap<Integer, pair> mp = new HashMap<Integer, pair>(); for ( int i = 0 ; i < n - 1 ; i++) for ( int j = i + 1 ; j < n; j++) mp.put(arr[i] + arr[j], new pair(i, j)); // Traverse through all pairs and search // for X - (current pair sum). for ( int i = 0 ; i < n - 1 ; i++) { for ( int j = i + 1 ; j < n; j++) { int sum = arr[i] + arr[j]; // If X - sum is present in hash table, if (mp.containsKey(X - sum)) { // Making sure that all elements are // distinct array elements and an // element is not considered more than // once. pair p = mp.get(X - sum); if (p.first != i && p.first != j && p.second != i && p.second != j) { System.out.print( arr[i] + ", " + arr[j] + ", " + arr[p.first] + ", " + arr[p.second]); return ; } } } } } // Driver Code public static void main(String[] args) { int arr[] = { 10 , 20 , 30 , 40 , 1 , 2 }; int n = arr.length; int X = 91 ; // Function call findFourElements(arr, n, X); } } // This code is contributed by Princi Singh |
Python3
# A hashing based Python program to find if there are # four elements with given summ. # The function finds four elements with given summ X def findFourElements(arr, n, X): # Store summs of all pairs in a hash table mp = {} for i in range (n - 1 ): for j in range (i + 1 , n): mp[arr[i] + arr[j]] = [i, j] # Traverse through all pairs and search # for X - (current pair summ). for i in range (n - 1 ): for j in range (i + 1 , n): summ = arr[i] + arr[j] # If X - summ is present in hash table, if (X - summ) in mp: # Making sure that all elements are # distinct array elements and an element # is not considered more than once. p = mp[X - summ] if (p[ 0 ] ! = i and p[ 0 ] ! = j and p[ 1 ] ! = i and p[ 1 ] ! = j): print (arr[i], ", " , arr[j], ", " , arr[p[ 0 ]], ", " , arr[p[ 1 ]], sep = "") return # Driver code arr = [ 10 , 20 , 30 , 40 , 1 , 2 ] n = len (arr) X = 91 # Function call findFourElements(arr, n, X) # This is code is contributed by shubhamsingh10 |
C#
// A hashing based C# program to find // if there are four elements with given sum. using System; using System.Collections.Generic; class GFG { public class pair { public int first, second; public pair( int first, int second) { this .first = first; this .second = second; } } // The function finds four elements // with given sum X static void findFourElements( int [] arr, int n, int X) { // Store sums of all pairs in a hash table Dictionary< int , pair> mp = new Dictionary< int , pair>(); for ( int i = 0; i < n - 1; i++) for ( int j = i + 1; j < n; j++) if (mp.ContainsKey(arr[i] + arr[j])) mp[arr[i] + arr[j]] = new pair(i, j); else mp.Add(arr[i] + arr[j], new pair(i, j)); // Traverse through all pairs and search // for X - (current pair sum). for ( int i = 0; i < n - 1; i++) { for ( int j = i + 1; j < n; j++) { int sum = arr[i] + arr[j]; // If X - sum is present in hash table, if (mp.ContainsKey(X - sum)) { // Making sure that all elements are // distinct array elements and an // element is not considered more than // once. pair p = mp[X - sum]; if (p.first != i && p.first != j && p.second != i && p.second != j) { Console.Write(arr[i] + ", " + arr[j] + ", " + arr[p.first] + ", " + arr[p.second]); return ; } } } } } // Driver Code public static void Main(String[] args) { int [] arr = { 10, 20, 30, 40, 1, 2 }; int n = arr.Length; int X = 91; // Function call findFourElements(arr, n, X); } } // This code is contributed by 29AjayKumar |
Javascript
<script> // A hashing based Javascript program to find // if there are four elements with given sum. // The function finds four elements // with given sum X function findFourElements(arr,n,X) { // Store sums of all pairs in a hash table let mp = new Map(); for (let i = 0; i < n - 1; i++) for (let j = i + 1; j < n; j++) mp.set(arr[i] + arr[j], [i, j]); // Traverse through all pairs and search // for X - (current pair sum). for (let i = 0; i < n - 1; i++) { for (let j = i + 1; j < n; j++) { let sum = arr[i] + arr[j]; // If X - sum is present in hash table, if (mp.has(X - sum)) { // Making sure that all elements are // distinct array elements and an // element is not considered more than // once. let p = mp.get(X - sum); if (p[0] != i && p[0] != j && p[1] != i && p[1] != j) { document.write( arr[i] + ", " + arr[j] + ", " + arr[p[0]] + ", " + arr[p[1]]); return ; } } } } } // Driver Code let arr=[ 10, 20, 30, 40, 1, 2]; let n = arr.length; let X = 91; // Function call findFourElements(arr, n, X); // This code is contributed by rag2127 </script> |
输出
20, 30, 40, 1
复杂性分析:
- 时间复杂性: O(n^2)。 需要嵌套遍历来存储哈希映射中的所有对。
- 辅助空间: O(n^2)。 所有n*(n-1)对都存储在哈希映射中,因此所需的空间为O(n^2) 如果您发现上述任何代码/算法不正确,请写下评论,或者寻找其他方法来解决相同的问题。
方法3: 没有重复元素的解决方案
方法:
- 将所有对的总和存储在哈希表中
- 再次遍历所有对,并在哈希表中搜索X–(当前对和)。
- 考虑初始存储零点的临时数组。当我们得到4个元素的总和达到所需的值时,它变为1。
- 如果找到具有所需总和的对,则确保所有元素都是不同的数组元素,并检查临时数组中的值是否为0,以便不考虑重复。
以下是代码的实现:
C++
// C++ program to find four // elements with the given sum #include <bits/stdc++.h> using namespace std; // Function to find 4 elements that add up to // given sum void fourSum( int X, int arr[], map< int , pair< int , int >> Map, int N) { int temp[N]; // Iterate from 0 to temp.length for ( int i = 0; i < N; i++) temp[i] = 0; // Iterate from 0 to arr.length for ( int i = 0; i < N - 1; i++) { // Iterate from i + 1 to arr.length for ( int j = i + 1; j < N; j++) { // Store curr_sum = arr[i] + arr[j] int curr_sum = arr[i] + arr[j]; // Check if X - curr_sum if present // in map if (Map.find(X - curr_sum) != Map.end()) { // Store pair having map value // X - curr_sum pair< int , int > p = Map[X - curr_sum]; if (p.first != i && p.second != i && p.first != j && p.second != j && temp[p.first] == 0 && temp[p.second] == 0 && temp[i] == 0 && temp[j] == 0) { // Print the output cout << arr[i] << "," << arr[j] << "," << arr[p.first] << "," << arr[p.second]; temp[p.second] = 1; temp[i] = 1; temp[j] = 1; break ; } } } } } // Program for two Sum map< int , pair< int , int >> twoSum( int nums[], int N) { map< int , pair< int , int >> Map; for ( int i = 0; i < N - 1; i++) { for ( int j = i + 1; j < N; j++) { Map[nums[i] + nums[j]].first = i; Map[nums[i] + nums[j]].second = j; } } return Map; } // Driver code int main() { int arr[] = { 10, 20, 30, 40, 1, 2 }; int n = sizeof (arr) / sizeof (arr[0]); int X = 91; map< int , pair< int , int >> Map = twoSum(arr, n); // Function call fourSum(X, arr, Map, n); return 0; } // This code is contributed by divyesh072019 |
JAVA
// Java program to find four // elements with the given sum import java.util.*; class fourElementWithSum { // Function to find 4 elements that add up to // given sum public static void fourSum( int X, int [] arr, Map<Integer, pair> map) { int [] temp = new int [arr.length]; // Iterate from 0 to temp.length for ( int i = 0 ; i < temp.length; i++) temp[i] = 0 ; // Iterate from 0 to arr.length for ( int i = 0 ; i < arr.length - 1 ; i++) { // Iterate from i + 1 to arr.length for ( int j = i + 1 ; j < arr.length; j++) { // Store curr_sum = arr[i] + arr[j] int curr_sum = arr[i] + arr[j]; // Check if X - curr_sum if present // in map if (map.containsKey(X - curr_sum)) { // Store pair having map value // X - curr_sum pair p = map.get(X - curr_sum); if (p.first != i && p.sec != i && p.first != j && p.sec != j && temp[p.first] == 0 && temp[p.sec] == 0 && temp[i] == 0 && temp[j] == 0 ) { // Print the output System.out.printf( "%d,%d,%d,%d" , arr[i], arr[j], arr[p.first], arr[p.sec]); temp[p.sec] = 1 ; temp[i] = 1 ; temp[j] = 1 ; break ; } } } } } // Program for two Sum public static Map<Integer, pair> twoSum( int [] nums) { Map<Integer, pair> map = new HashMap<>(); for ( int i = 0 ; i < nums.length - 1 ; i++) { for ( int j = i + 1 ; j < nums.length; j++) { map.put(nums[i] + nums[j], new pair(i, j)); } } return map; } // to store indices of two sum pair public static class pair { int first, sec; public pair( int first, int sec) { this .first = first; this .sec = sec; } } // Driver Code public static void main(String args[]) { int [] arr = { 10 , 20 , 30 , 40 , 1 , 2 }; int n = arr.length; int X = 91 ; Map<Integer, pair> map = twoSum(arr); // Function call fourSum(X, arr, map); } } // This code is contributed by Likhita avl. |
Python3
# Python3 program to find four # elements with the given sum # Function to find 4 elements that # add up to given sum def fourSum(X, arr, Map , N): temp = [ 0 for i in range (N)] # Iterate from 0 to length of arr for i in range (N - 1 ): # Iterate from i + 1 to length of arr for j in range (i + 1 , N): # Store curr_sum = arr[i] + arr[j] curr_sum = arr[i] + arr[j] # Check if X - curr_sum if present # in map if (X - curr_sum) in Map : # Store pair having map value # X - curr_sum p = Map [X - curr_sum] if (p[ 0 ] ! = i and p[ 1 ] ! = i and p[ 0 ] ! = j and p[ 1 ] ! = j and temp[p[ 0 ]] = = 0 and temp[p[ 1 ]] = = 0 and temp[i] = = 0 and temp[j] = = 0 ): # Print the output print (arr[i], "," , arr[j], "," , arr[p[ 0 ]], "," , arr[p[ 1 ]], sep = "") temp[p[ 1 ]] = 1 temp[i] = 1 temp[j] = 1 break # Function for two Sum def twoSum(nums, N): Map = {} for i in range (N - 1 ): for j in range (i + 1 , N): Map [nums[i] + nums[j]] = [] Map [nums[i] + nums[j]].append(i) Map [nums[i] + nums[j]].append(j) return Map # Driver code arr = [ 10 , 20 , 30 , 40 , 1 , 2 ] n = len (arr) X = 91 Map = twoSum(arr, n) # Function call fourSum(X, arr, Map , n) # This code is contributed by avanitrachhadiya2155 |
C#
// C# program to find four // elements with the given sum using System; using System.Collections.Generic; class GFG { // Function to find 4 elements that add up to // given sum static void fourSum( int X, int [] arr, Dictionary< int , Tuple< int , int >> Map, int N) { int [] temp = new int [N]; // Iterate from 0 to temp.length for ( int i = 0; i < N; i++) temp[i] = 0; // Iterate from 0 to arr.length for ( int i = 0; i < N - 1; i++) { // Iterate from i + 1 to arr.length for ( int j = i + 1; j < N; j++) { // Store curr_sum = arr[i] + arr[j] int curr_sum = arr[i] + arr[j]; // Check if X - curr_sum if present // in map if (Map.ContainsKey(X - curr_sum)) { // Store pair having map value // X - curr_sum Tuple< int , int > p = Map[X - curr_sum]; if (p.Item1 != i && p.Item2 != i && p.Item1 != j && p.Item2 != j && temp[p.Item1] == 0 && temp[p.Item2] == 0 && temp[i] == 0 && temp[j] == 0) { // Print the output Console.Write(arr[i] + "," + arr[j] + "," + arr[p.Item1] + "," + arr[p.Item2]); temp[p.Item2] = 1; temp[i] = 1; temp[j] = 1; break ; } } } } } // Program for two Sum static Dictionary< int , Tuple< int , int >> twoSum( int [] nums, int N) { Dictionary< int , Tuple< int , int >> Map = new Dictionary< int , Tuple< int , int >>(); for ( int i = 0; i < N - 1; i++) { for ( int j = i + 1; j < N; j++) { Map[nums[i] + nums[j]] = new Tuple< int , int >(i, j); } } return Map; } // Driver code static void Main() { int [] arr = { 10, 20, 30, 40, 1, 2 }; int n = arr.Length; int X = 91; Dictionary< int , Tuple< int , int >> Map = twoSum(arr, n); // Function call fourSum(X, arr, Map, n); } } // This code is contributed by divyeshrabadiya07 |
Javascript
<script> // Javascript program to find four // elements with the given sum class pair { constructor(first, sec) { this .first = first; this .sec = sec; } } // Function to find 4 elements that add up to // given sum function fourSum(X, arr, map) { let temp = new Array(arr.length); // Iterate from 0 to temp.length for (let i = 0; i < temp.length; i++) temp[i] = 0; // Iterate from 0 to arr.length for (let i = 0; i < arr.length - 1; i++) { // Iterate from i + 1 to arr.length for (let j = i + 1; j < arr.length; j++) { // Store curr_sum = arr[i] + arr[j] let curr_sum = arr[i] + arr[j]; // Check if X - curr_sum if present // in map if (map.has(X - curr_sum)) { // Store pair having map value // X - curr_sum let p = map.get(X - curr_sum); if (p.first != i && p.sec != i && p.first != j && p.sec != j && temp[p.first] == 0 && temp[p.sec] == 0 && temp[i] == 0 && temp[j] == 0) { // Print the output document.write( arr[i]+ "," +arr[j]+ "," + arr[p.first]+ "," +arr[p.sec]); temp[p.sec] = 1; temp[i] = 1; temp[j] = 1; break ; } } } } } // Program for two Sum function twoSum(nums) { let map = new Map(); for (let i = 0; i < nums.length - 1; i++) { for (let j = i + 1; j < nums.length; j++) { map.set(nums[i] + nums[j], new pair(i, j)); } } return map; } // Driver Code let arr=[10, 20, 30, 40, 1, 2]; let n = arr.length; let X = 91; let map = twoSum(arr); // Function call fourSum(X, arr, map); // This code is contributed by patel2127. </script> |
输出
20,30,40,1
复杂性分析:
- 时间复杂性: O(n^2)。 需要嵌套遍历来存储哈希映射中的所有对。
- 辅助空间: O(n^2)。 所有n*(n-1)对都存储在哈希映射中,因此所需的空间为O(n^2),临时数组取O(n),因此空间为O(n^2)。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END