【July程序员编程艺术】之寻找和为定值的两个或者多个数

一.寻找和为定值的两个数

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

我的思路:题目要求时间复杂度是O(n),所以整个数组只可以遍历一轮。针对题目中给出的实例,对于数4,我们实际上就是要找数组中可有15-4=11这个数。将原题进行这样的转化之后,很容易想到使用hash表,只需要遍历一次数组,即可根据数值在O(1)的时间得到其的存储位置。C++ STL里面封装了hash_map的实现,编写程序如下:

#include 
#include 
using namespace std;
map<int, int> hash_map;

void search(int * src ,map<int,int> & map,int value,int & a,int & b,int len)
{

    for(int i=0;iif(hash_map[value-src[i]]==1)
        {
            a = src[i];
            b=value-src[i];
            break;
        }
    }


}

博客中还给出了指针夹逼的思路,利用两个指针,从两端进行遍历。联想之前的字符串题目中,也有使用两个指针分别在两个字符串中进行遍历的操作。对于有些问题,如果涉及到两个元素的比较或者求和,使用两个指针进行遍历,往往能起到比较好的效果。实现程序如下:

void point_search(int * src,int len,int value,int & a,int & b)
{
    int * pa = src;
    int * pb = src+len-1;
     int tmp_sum=(*pa)+(*pb);
     while(paif(tmp_sum<value)
             pa++;
         if(tmp_sum>value)
             pb--;
         if(tmp_sum==value)
         {
             a = *pa;
             b = *pb;
             break;
         }
     }
}

二.寻找和为定值的多个数

题目描述:输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数,
使其和等于 m ,要求将其中所有的可能组合列出来。

我的解题思路:
首先自己举个例子,如果数组是1,2,3,4,5,要寻找和为7的元素的组合,那么人的思路自然是2+5=7,然后在对5进行分解这样,这就是递归的思想。因此,可以使用递归的程序,实现如下:

#include  
#include  
using namespace std;  

list<int>list1;  
void find_factor(int sum, int n)   
{  
    // 递归出口  
    if(sum==0)
    {
        // 反转list  
        list1.reverse();  
        for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)  
            cout << *iter << " + ";  
        cout  << endl;  
        list1.reverse();   
        return;
    }
  if(n<=0)
      return;



    list1.push_front(n);      //典型的01背包问题  
    if(n-1>sum-n)
        find_factor(sum-n, sum-n);   //放n,n-1个数填满sum-n 
    else
        find_factor(sum-n, n-1);
    list1.pop_front();  
    find_factor(sum, n-1);     //不放n,n-1个数填满sum   
}  

int main()  
{  
    int sum, n;  
    sum=7;
    n=4;
    cout << "所有可能的序列,如下:" << endl;  
    find_factor(sum,n);  
    return 0;  
}  

对比我实现的程序和July实现的程序,
if(n-1>sum-n)
find_factor(sum-n, sum-n); //放n,n-1个数填满sum-n
else
find_factor(sum-n, n-1);
我在这里加了一个if语句进行判断,这样的效率会高些。比如说寻找和为20,第一次将19送入列表,接下来自然应该是find(1,1),而July实现的是find(1,18),这样会多做许多无用功。
之后的例子没有细看,应用到了动态规划,回溯法这些思想,这些算法思想之前上过课,原理基本明白,但是没有实现过。以后有时间再自己去实现。

你可能感兴趣的:(算法练习)