📌  相关文章
📜  C ++程序查找总和为给定值的三元组

📅  最后修改于: 2022-05-13 01:55:05.086000             🧑  作者: Mango

C ++程序查找总和为给定值的三元组

给定一个数组和一个值,找出数组中是否存在一个三元组,其和等于给定值。如果数组中存在这样的三元组,则打印三元组并返回 true。否则返回假。

例子:

方法1这是解决上述问题的幼稚方法。

  • 方法:一种简单的方法是生成所有可能的三元组,并将每个三元组的总和与给定值进行比较。下面的代码使用三个嵌套循环来实现这个简单的方法。
  • 算法:
    1. 给定一个长度为n的数组和一个总和s
    2. 创建三个嵌套循环,第一个循环从开始到结束运行(循环计数器 i),第二个循环从 i+1 运行到结束(循环计数器 j),第三个循环从 j+1 运行到结束(循环计数器 k)
    3. 这些循环的计数器表示三元组的 3 个元素的索引。
    4. 求第 i 个、第 j 个和第 k 个元素的总和。如果总和等于给定总和。打印三元组并中断。
    5. 如果没有三元组,则打印不存在三元组。
  • 执行:
C++
#include 
using namespace std;
  
// returns true if there is triplet with sum equal 
// to 'sum' present in A[]. Also, prints the triplet 
bool find3Numbers(int A[], int arr_size, int sum) 
{ 
    int l, r; 
  
    // Fix the first element as A[i] 
    for (int i = 0; i < arr_size - 2; i++)
    { 
  
        // Fix the second element as A[j] 
        for (int j = i + 1; j < arr_size - 1; j++)
        { 
  
            // Now look for the third number 
            for (int k = j + 1; k < arr_size; k++)
            { 
                if (A[i] + A[j] + A[k] == sum)
                { 
                    cout << "Triplet is " << A[i] <<
                        ", " << A[j] << ", " << A[k]; 
                    return true; 
                } 
            } 
        } 
    } 
  
    // If we reach here, then no triplet was found 
    return false; 
} 
  
/* Driver code */
int main() 
{ 
    int A[] = { 1, 4, 45, 6, 10, 8 }; 
    int sum = 22; 
    int arr_size = sizeof(A) / sizeof(A[0]); 
    find3Numbers(A, arr_size, sum); 
    return 0; 
} 
  
// This is code is contributed by rathbhupendra


C++
// C++ program to find a triplet
#include 
using namespace std;
  
// returns true if there is triplet with sum equal
// to 'sum' present in A[]. Also, prints the triplet
bool find3Numbers(int A[], int arr_size, int sum)
{
    int l, r;
  
    /* Sort the elements */
    sort(A, A + arr_size);
  
    /* Now fix the first element one by one and find the
       other two elements */
    for (int i = 0; i < arr_size - 2; i++) {
  
        // To find the other two elements, start two index
        // variables from two corners of the array and move
        // them toward each other
        l = i + 1; // index of the first element in the
        // remaining elements
  
        r = arr_size - 1; // index of the last element
        while (l < r) {
            if (A[i] + A[l] + A[r] == sum) {
                printf("Triplet is %d, %d, %d", A[i],
                       A[l], A[r]);
                return true;
            }
            else if (A[i] + A[l] + A[r] < sum)
                l++;
            else // A[i] + A[l] + A[r] > sum
                r--;
        }
    }
  
    // If we reach here, then no triplet was found
    return false;
}
  
/* Driver program to test above function */
int main()
{
    int A[] = { 1, 4, 45, 6, 10, 8 };
    int sum = 22;
    int arr_size = sizeof(A) / sizeof(A[0]);
  
    find3Numbers(A, arr_size, sum);
  
    return 0;
}


C++
// C++ program to find a triplet using Hashing
#include 
using namespace std;
  
// returns true if there is triplet with sum equal
// to 'sum' present in A[]. Also, prints the triplet
bool find3Numbers(int A[], int arr_size, int sum)
{
    // Fix the first element as A[i]
    for (int i = 0; i < arr_size - 2; i++) 
    {
  
        // Find pair in subarray A[i+1..n-1]
        // with sum equal to sum - A[i]
        unordered_set s;
        int curr_sum = sum - A[i];
        for (int j = i + 1; j < arr_size; j++) 
        {
            if (s.find(curr_sum - A[j]) != s.end()) 
            {
                printf("Triplet is %d, %d, %d", A[i],
                       A[j], curr_sum - A[j]);
                return true;
            }
            s.insert(A[j]);
        }
    }
  
    // If we reach here, then no triplet was found
    return false;
}
  
/* Driver program to test above function */
int main()
{
    int A[] = { 1, 4, 45, 6, 10, 8 };
    int sum = 22;
    int arr_size = sizeof(A) / sizeof(A[0]);
  
    find3Numbers(A, arr_size, sum);
  
    return 0;
}


输出
Triplet is 4, 10, 8

  • 复杂性分析:
    • 时间复杂度: O(n 3 )。
      遍历数组有3个嵌套循环,所以时间复杂度为O(n^3)
    • 空间复杂度: O(1)。
      因为不需要额外的空间。

方法二:这种方法使用排序来提高代码的效率。

  • 方法:通过对数组进行排序,可以提高算法的效率。这种有效的方法使用两指针技术。遍历数组并修复三元组的第一个元素。现在使用两个指针算法来查找是否存在总和等于 x – array[i] 的对。两个指针算法需要线性时间,因此它比嵌套循环更好。
  • 算法 :
    1. 对给定的数组进行排序。
    2. 循环遍历数组并修复可能的三元组的第一个元素 arr[i]。
    3. 然后固定两个指针,一个在 i + 1,另一个在 n – 1。看看总和,
      1. 如果总和小于所需总和,则递增第一个指针。
      2. 否则,如果总和较大,则减小结束指针以减少总和。
      3. 否则,如果两个指针处的元素之和等于给定的和,则打印三元组并中断。
  • 执行:

C++

// C++ program to find a triplet
#include 
using namespace std;
  
// returns true if there is triplet with sum equal
// to 'sum' present in A[]. Also, prints the triplet
bool find3Numbers(int A[], int arr_size, int sum)
{
    int l, r;
  
    /* Sort the elements */
    sort(A, A + arr_size);
  
    /* Now fix the first element one by one and find the
       other two elements */
    for (int i = 0; i < arr_size - 2; i++) {
  
        // To find the other two elements, start two index
        // variables from two corners of the array and move
        // them toward each other
        l = i + 1; // index of the first element in the
        // remaining elements
  
        r = arr_size - 1; // index of the last element
        while (l < r) {
            if (A[i] + A[l] + A[r] == sum) {
                printf("Triplet is %d, %d, %d", A[i],
                       A[l], A[r]);
                return true;
            }
            else if (A[i] + A[l] + A[r] < sum)
                l++;
            else // A[i] + A[l] + A[r] > sum
                r--;
        }
    }
  
    // If we reach here, then no triplet was found
    return false;
}
  
/* Driver program to test above function */
int main()
{
    int A[] = { 1, 4, 45, 6, 10, 8 };
    int sum = 22;
    int arr_size = sizeof(A) / sizeof(A[0]);
  
    find3Numbers(A, arr_size, sum);
  
    return 0;
}
输出
Triplet is 4, 8, 10
  • 复杂性分析:
    • 时间复杂度: O(N^2)。
      遍历数组的嵌套循环只有两个,所以时间复杂度为 O(n^2)。双指针算法需要 O(n) 时间,第一个元素可以使用另一个嵌套遍历来固定。
    • 空间复杂度: O(1)。
      因为不需要额外的空间。

方法 3这是一个基于散列的解决方案。

  • 方法:这种方法使用额外的空间,但比两指针方法更简单。从开始到结束运行两个循环外循环和从 i+1 到结束的内循环。创建一个 hashmap 或 set 来存储 i+1 到 j-1 之间的元素。因此,如果给定的总和是 x,请检查集合中是否存在等于 x – arr[i] – arr[j] 的数字。如果是,则打印三元组。
  • 算法:
    1. 从头到尾遍历数组。 (循环计数器 i)
    2. 创建一个 HashMap 或设置以存储唯一对。
    3. 运行从 i+1 到数组末尾的另一个循环。 (循环计数器 j)
    4. 如果集合中有一个元素等于 x-arr[i] – arr[j],则打印三元组 (arr[i], arr[j], x-arr[i]-arr[j] ) 并打破
    5. 在集合中插入第 j 个元素。
  • 执行:

C++

// C++ program to find a triplet using Hashing
#include 
using namespace std;
  
// returns true if there is triplet with sum equal
// to 'sum' present in A[]. Also, prints the triplet
bool find3Numbers(int A[], int arr_size, int sum)
{
    // Fix the first element as A[i]
    for (int i = 0; i < arr_size - 2; i++) 
    {
  
        // Find pair in subarray A[i+1..n-1]
        // with sum equal to sum - A[i]
        unordered_set s;
        int curr_sum = sum - A[i];
        for (int j = i + 1; j < arr_size; j++) 
        {
            if (s.find(curr_sum - A[j]) != s.end()) 
            {
                printf("Triplet is %d, %d, %d", A[i],
                       A[j], curr_sum - A[j]);
                return true;
            }
            s.insert(A[j]);
        }
    }
  
    // If we reach here, then no triplet was found
    return false;
}
  
/* Driver program to test above function */
int main()
{
    int A[] = { 1, 4, 45, 6, 10, 8 };
    int sum = 22;
    int arr_size = sizeof(A) / sizeof(A[0]);
  
    find3Numbers(A, arr_size, sum);
  
    return 0;
}

输出:

Triplet is 4, 8, 10

时间复杂度: O(N^2)
辅助空间: O(N)

有关详细信息,请参阅有关查找总和为给定值的三元组的完整文章!