• 编程之美2.12快速寻找满足条件的2个数


    题目:

    对于一个数组,快速找出两个数字,让这两个数字的和等于一个给定的值,默认假设数组中肯定有至少一组符合要求。

    数组a[]={5,6,1,4,7,8,9},sum=10.

    解法一:

    穷举,遍历数组中所有的2个数字,相加之和看是否等于给定的数字,时间复杂度为N(N-1)/2,既O(N^2),这种方法效率不高。

     1 #include "iostream"
     2 using namespace std;
     3 
     4 void sum(int *a,int N){
     5     for(int i=0;i<N;i++){
     6         for(int j=i+1;j<N;j++)
     7         if(a[i]+a[j]==10)
     8             cout<<"a="<<a[i]<<" b="<<a[j]<<endl;
     9     }
    10 }
    11 int main(){
    12     int data[] = {5, 6, 1, 4, 7, 9, 8};
    13     int length=sizeof(data)/sizeof(data[0]);
    14     sum(data,length);
    15 } 

    解法二:
    求2个数字之和,假定和为sum,对于元素a[i]只需判断数组中是否存在sum-a[i],无序数组中查找一个数的时间复杂度为O(n),不对数组进行操作的时间复杂度仍为O(n^2)。如果对数组进行排序,然后才去二分查找的方法,查找一个元素的时间复杂度为O(log2n),总时间复杂度为O(n*log2n)。而排序的过程只需要进行一次,时间复杂度为O(N*log2n),所以总时间复杂度仍为O(n*log2n)。

    解法三:

    换个角度,对于有序序列,从两头分别取数,之和大于sum,j--,之和大于sumi++。将排序号的数组遍历一遍即可输出全部的结果。

     1 #include "iostream"
     2 #include "algorithm"
     3 using namespace std;
     4 
     5 void sum(int *a,int N){
     6 int i,j;
     7     for(i = 0,j = N-1;i<j;){
     8         if(a[i]+a[j]==10){
     9             cout<<a[i]<<","<<a[j]<<endl;
    10             i++;
    11         }
    12         else if(a[i]+a[j]<10)
    13             i++;
    14         else 
    15             j--;
    16     }
    17 }
    18 int main(){
    19     int data[] = {5, 6, 1, 4, 7, 9, 8};
    20     sort(data, data+7);   //快速排序 
    21     int length=sizeof(data)/sizeof(data[0]);
    22     sum(data,length);
    23 } 


    扩展问题:

    1,将两个数字改为3个数字。

    假设找到了3个数ai,aj,ak,ai+aj+ak=sum,既ai+aj=sum-ak。i,k从左侧遍历,j从右侧遍历。以sum=17为例,会输出三组满足条件的数。

     1 #include "iostream"
     2 #include "algorithm"
     3 using namespace std;
     4 
     5 void sum(int *a,int N){
     6 int i,j,k;
     7 for(k=0;k<N;k++)
     8     for(i = k+1,j = N-k-1;i<j;){
     9         if(a[i]+a[j]+a[k]==17){
    10             cout<<a[i]<<","<<a[j]<<","<<a[k]<<endl;
    11             i++;
    12         }
    13         else if(a[i]+a[j]+a[k]<17)
    14             i++;
    15         else 
    16             j--;
    17     }
    18 }
    19 int main(){
    20     int data[] = {5, 6, 1, 4, 7, 9, 8};
    21     sort(data, data+7);   //快速排序 
    22     int length=sizeof(data)/sizeof(data[0]);
    23     sum(data,length);
    24 } 
  • 相关阅读:
    《手把手教你构建自己的 Linux 系统》学习笔记(7)
    《手把手教你构建自己的 Linux 系统》学习笔记(6)
    《手把手教你构建自己的 Linux 系统》学习笔记(5)
    《手把手教你构建自己的 Linux 系统》学习笔记(4)
    《手把手教你构建自己的 Linux 系统》学习笔记(3)
    《手把手教你构建自己的 Linux 系统》学习笔记(2)
    《手把手教你构建自己的 Linux 系统》学习笔记(1)
    Mac 下如何判断 WIFI 的极限传输速度还有信号强度?
    Mac 下如何快速重启 Dock 栏?
    编译器的工作过程
  • 原文地址:https://www.cnblogs.com/SeekHit/p/5198472.html
Copyright © 2020-2023  润新知