• 寻找和为定值的两个数


    题目:输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
    要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
    例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。

    解析:如果数组是无序的,先排序(n*logn),然后用两个指针i,j,各自指向数组的首尾两端,令i=0,j=n-1,然后i++,j--,逐次判断 a[i]+a[j]?=sum,如果某一刻a[i]+a[j]>sum,则要想办法让sum的值减小,所以此刻i不动,j--,如果某一刻 a[i]+a[j]<sum,则要想办法让sum的值增大,所以此刻i++,j不动。所以,数组无序的时候,时间复杂度最终为 O(n*logn+n)=O(n*logn),若原数组是有序的,则不需要事先的排序,直接O(n)搞定,且空间复杂度还是O(1),此思路是相对于上述 所有思路的一种改进。(如果有序,直接两个指针两端扫描,时间O(N),如果无序,先排序后两端扫描,时间O(N*logN+N)=O(N*logN),空间始终都为O(1))

    总结

    • 不论原序列是有序还是无序,解决这类题有以下三种办法:1、二分(若无序,先排 序后二分),时间复杂度总为O(n*logn),空间复杂度为O(1);2、扫描一遍X-S[i]  映射到一个数组或构造hash表,时间复杂度为O(n),空间复杂度为O(n);3、两个指针两端扫描(若无序,先排序后扫描),时间复杂度最后为:有序 O(n),无序O(n*logn+n)=O(n*logn),空间复杂度都为O(1)。
    • 所以,要想达到时间O(N),空间O(1)的目 标,除非原数组是有序的(指针扫描法),不然,当数组无序的话,就只能先排序,后指针扫描法或二分(时间n*logn,空间O(1)),或映射或 hash(时间O(n),空间O(n))。时间或空间,必须牺牲一个,自个权衡吧。
    • 综上,若是数组有序的情况下,优先考虑两个指针两端扫描法,以达到最佳的时(O(N)),空(O(1))效应。否则,如果要排序的话,时间复杂度最快当然是只能达到N*logN,空间O(1)则是不在话下。

    这里假定数组已经是有序的,代码可以如下编写(两段代码实现):

    bool FindNumbersWithSum(int data[], int length, int sum, int *num1, int *num2)
    {
        bool found = false;
        if(length < 1 || num1 == NULL || num2 == NULL)
            return false;
         
        int ahead = length - 1;
        int behind = 0;
         
        while(ahead > behind)
        {
            long long curSum = data[ahead] + data[behind];
            if(curSum == sum)
            {
                *num1 = data[behind];
                *num2 = data[ahead];
                found = true;
                break;
            }
            else if(curSum > sum)
                ahead--;
            else
                behind++;
        }
        return found;
    }

     测试代码:

     1 #include<iostream>
     2 using namespace std;
     3 
     4 bool find_num(int data[] , int length , int sum , int &first_num , int &second_num)
     5 {
     6     if(length < 1)
     7         return true;
     8 
     9     int begin = 0;
    10     int end = length - 1;
    11 
    12     while(begin < end)
    13     {
    14         int current_sum = data[begin] + data[end];
    15 
    16         if(current_sum == sum)
    17         {
    18             first_num = data[begin];
    19             second_num = data[end];
    20             return true;
    21         }
    22         else if(current_sum > sum)
    23             end--;
    24         else 
    25             begin++;
    26     }
    27     return false;
    28 }
    29 
    30 int main()
    31 {
    32     int data[] = {1 , 2 , 4 , 7 , 11 , 15};
    33     int length = sizeof(data)/sizeof(int);
    34     int first_num = 0 ;
    35     int second_num = 0;
    36     int sum = 15;
    37 
    38     if(find_num(data , length , 15 , first_num , second_num))
    39     {
    40         cout<<first_num<<" "<<second_num<<endl;
    41     }
    42     else
    43         cout<<"not exist!"<<endl;
    44 
    45     return 0;
    46 }
    寻找是否存在两个数的和为定值

    寻找和为定值的多个数:

    2010年中兴面试题
    编程求解:
    输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,
    使其和等于 m ,要求将其中所有的可能组合列出来。
     1 #include<list>  
     2 #include<iostream>  
     3 using namespace std;  
     4   
     5 list<int>list1;  
     6 void find_factor(int sum, int n)   
     7 {  
     8     // 递归出口  
     9     if(n <= 0 || sum <= 0)  
    10         return;  
    11       
    12     // 输出找到的结果  
    13     if(sum == n)  
    14     {  
    15         // 反转list  
    16         list1.reverse();  
    17         for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)  
    18             cout << *iter << " + ";  
    19         cout << n << endl;  
    20         list1.reverse();      
    21     }  
    22       
    23     list1.push_front(n);      //典型的01背包问题  
    24     find_factor(sum-n, n-1);   //放n,n-1个数填满sum-n  
    25     list1.pop_front();  
    26     find_factor(sum, n-1);     //不放n,n-1个数填满sum   
    27 }  
    28   
    29 int main()  
    30 {  
    31     int sum, n;  
    32     cout << "请输入你要等于多少的数值sum:" << endl;  
    33     cin >> sum;  
    34     cout << "请输入你要从1.....n数列中取值的n:" << endl;  
    35     cin >> n;  
    36     cout << "所有可能的序列,如下:" << endl;  
    37     find_factor(sum,n);  
    38     return 0;  
    39 }  

     http://blog.csdn.net/v_JULY_v/article/details/6419466

  • 相关阅读:
    获取mysql数据库中的表信息
    Django Rest Framework --- 分页器组件
    Django Rest Framework --- 频率组件
    Django Rest Framework --- 权限组件
    Django Rest Framework --- 认证组件
    Django Rest Framework --- 视图组件
    序列化组件
    restful规范,cbv源码执行流程,drf之APIView及Respons源码分析
    前后台分离式开发(文件的上传下载),cookie(存放在前台),session(存放在后台)
    ajax,分页器
  • 原文地址:https://www.cnblogs.com/heyonggang/p/3386038.html
Copyright © 2020-2023  润新知