zoukankan      html  css  js  c++  java
  • 算法系列:三元组和


    思路1:可以用hash表来存储数组中的元素,这样我们取得一个数后,去判断sum - val 在不在数组中,如果在数组中,则找到了一对二元组,它们的和为sum,该算法的缺点就是需要用到一个hash表,增加了空间复杂度。

    思路2:同样是基于查找,我们可以先将数组排序,然后依次取一个数后,在数组中用二分查找,查找sum -val是否存在,如果存在,则找到了一对二元组,它们的和为sum,该方法与上面的方法相比,虽然不用实现一个hash表,也没不需要过多的空间,但是时间多了很多。排序需要O(nLogn),二分查找需要(Logn),查找n次,所以时间复杂度为O(nLogn)。

    思路3:该方法基于第2种思路,但是进行了优化,在时间复杂度和空间复杂度是一种折中,但是算法的简单直观、易于理解。首先将数组排序,然后用两个指向数组的指针,一个从前往后扫描,一个从后往前扫描,记为first和last,如果 fist + last < sum 则将fist向前移动,如果fist + last > sum,则last向后移动。

     

    [cpp] view plain copy
     
     print?
    1. #include <iostream>  
    2. #include <algorithm>  
    3. using namespace std;  
    4.   
    5. void printPairSums(int data[], int size, int sum);  
    6. int main(int argc, char* argv[])  
    7. {  
    8.     int data[] = {1, 5, 9, -1, 4, 6, -2, 3, -8};  
    9.     int size = sizeof(data) / sizeof(data[0]);  
    10.     int i;  
    11.     sort(data, data + size);  
    12.     printPairSums(data, size, 8);  
    13.   
    14.     return 0;  
    15. }  
    16. void printPairSums(int data[], int size, int sum)  
    17. {  
    18.     int first = 0;  
    19.     int last = size -1;  
    20.     int s = 0;  
    21.     while (first < last)  
    22.     {  
    23.         s = data[first] + data[last];  
    24.         if (s == sum)  
    25.         {  
    26.             cout << data[first] << " + " << data[last] << " = " << sum << endl;  
    27.             first++;  
    28.             last--;  
    29.         }  
    30.         else if (s < sum)  
    31.         {  
    32.             first++;  
    33.         }  
    34.         else  
    35.         {  
    36.             last--;  
    37.         }  
    38.     }  
    39. }  


     

    思路:  对于二元组的和等于给定值的情况,可以参考http://blog.csdn.net/lalor/article/details/7554594, 即将数组排序后,用两个指向数组的指针,一个从前向后扫描,一个从后向前扫描,记为first和last,当first + last == sum 则找到了一对二元组,它们的和等于sum,如果first + last < sum 则 first++, first + last > sum 则last--。同样,三元组的情况,先将数组排序,然后固定一个元素,再去寻找一个二元组的和为sum - val,这样就将三元组的问题,转换成了二元组的问题。


    程序如下:

     

    [cpp] view plain copy
     
     print?
    1. #include <iostream>  
    2. #include <algorithm>  
    3.   
    4. using namespace std;  
    5.   
    6. bool find3Numbers(int A[], int arr_size, int sum)  
    7. {  
    8.     int l, r;  
    9.     /* Sort the elements */  
    10.     sort(A, A + arr_size);  
    11.   
    12.     /* Now fix the first element one by one and find the  
    13.      * other two elements 
    14.      */  
    15.     for (int i = 0; i < arr_size - 2; i++)   
    16.     {  
    17.         // to find the other two elements, start two index variables  
    18.         //from two corners of the array and move toward each other  
    19.   
    20.         l = i + 1; //index of the first element in the remaining elements  
    21.         r = arr_size - 1;//index of the last element  
    22.   
    23.         while (l < r)   
    24.         {  
    25.             if (A[i] + A[l] + A[r] == sum)   
    26.             {  
    27.                 cout << "Triplet is " << A[i] << " " << A[l] << " " << A[r] << endl;  
    28.                 return true;  
    29.             }  
    30.             else if (A[i] + A[l] + A[r] < sum)   
    31.             {  
    32.                 l++;  
    33.             }  
    34.             else // A[i] + A[l] + A[r] > sum  
    35.             {  
    36.                 r--;  
    37.             }  
    38.               
    39.         }  
    40.     }  
    41.     // If we reach here, then no triplet was found  
    42.     return false;  
    43. }  
    44.   
    45. /* Driver program to test above function */  
    46. int main(int argc, char* argv[])  
    47. {  
    48.     int A[] = {1, 4, 45, 6, 10, 8};  
    49.     int sum = 22;  
    50.     int arr_size = sizeof(A) / sizeof(A[0]);  
    51.   
    52.     find3Numbers(A, arr_size, sum);  
    53.     return 0;  
    54. }  


    方法2(回溯法),也能得到不错的效率

     

     

    [cpp] view plain copy
     
     print?
    1. #include <iostream>  
    2. #include <algorithm>  
    3.   
    4. using namespace std;  
    5.   
    6. const int S = 22;  
    7.   
    8. int sumCheck(int A[], int start, int end, int arr[], int cnt)  
    9. {  
    10.     if (cnt == 2)   
    11.     {  
    12.         int sum = arr[0] + arr[1] + arr[2];  
    13.         if (sum == S)   
    14.         {  
    15.             cout << arr[0] << " " << arr[1] << " " << arr[2] << endl;  
    16.         }  
    17.         return 0;  
    18.     }  
    19.   
    20.     if (start > end || cnt > 2)   
    21.     {  
    22.         return -1;  
    23.     }  
    24.   
    25.     int i = start;  
    26.   
    27.       
    28.     arr[++cnt] = A[i];  
    29.     sumCheck(A, start + 1, end, arr, cnt);  
    30.     arr[cnt] = 0;  
    31.     cnt--;  
    32.     sumCheck(A, start + 1, end, arr, cnt);  
    33. }  
    34.   
    35. /* Driver program to test above function */  
    36. int main(int argc, char* argv[])  
    37. {  
    38.     int A[] = {1, 4, 45, 6, 10, 8};  
    39.     int arr_size = sizeof(A) / sizeof(A[0]);  
    40.     int cnt = -1;  
    41.     int arr[3] = {0, 0, 0};  
    42.   
    43.     sumCheck(A,0, arr_size-1, arr, cnt);  
    44.     return 0;  
    45. }  
  • 相关阅读:
    远程服务器上的weblogic项目管理(二)发布完成后如何重启weblogic容器
    Oracle中日期和时间类函数
    程序员应如何提高实效?读《程序员修炼之道》有感
    远程服务器上的weblogic项目管理(一)项目部署与更新流程
    远程服务器上的weblogic项目管理(四)filelock not found错误解决方法
    浅拷贝与深拷贝
    for...of 与 for...in
    工厂函数创建对象
    Promise
    闭包内存泄漏解决方法
  • 原文地址:https://www.cnblogs.com/noryes/p/5716667.html
Copyright © 2011-2022 走看看