Two Sum

之前遇到一道题和这个基本一样,数组中元素各不相同,另外创建一个数组,里面的元素为target依次减去原数组中所有元素,然后两个数组合并,排序,扫描,如果有相邻元素相等并且不等于target的一半,则说明原数组中有两个不同的元素和为target。

不过这个题目的返回值是两个,这个怎么做到?而且函数的返回值类型为vector<int>······

这个我现在真不会,参看了别人的写法才知道是这么写的:vector<int> ret(2, 0)

Submission Result: Runtime Error ,不要怕错,要从错误中吸取经验和教训

 1 class Solution {
 2 public:
 3     vector<int> twoSum(vector<int> &numbers, int target) {
 4         vector<int> ret(2,0);
 5         int n=numbers.size();
 6         int i;
 7         vector<int> num;
 8         for(i=0;i<n;++i)
 9         {
10             num.push_back(target-numbers[i]);
11             num.push_back(numbers[i]);
12         }
13         //sort(num,num+2*n);  //Line 13: no match for 'operator+' in 'num + (n * 2)'
14         sort(num.begin(),num.end());
15         for(i=0;i<2*n-1;++i)
16         {
17             if(num[i]==num[i+1]&&num[i]!=target/2)//感觉不太对吧,题上没有说元素互不相等的
18             {
19                 ret[0]=num[i];//ret是用来返回下标的,这里先借来存储那两个值
20                 ret[1]=target-num[i];
21                 //cout<<"调试信息:num[i]="<<num[i]<<" num[i+1]="<<num[i+1]<<" target-num[i]="<<target-num[i]<<endl;//调试信息
22                 break;
23             }
24         }
25         int j=0;
26         for(i=0;i<n;++i)//没有说原数组有序,所以还要比较ret内存的两个值,如果不符合题意,交换之
27         {
28             /*
29             if(numbers[i]==ret[0])
30             {
31                 ret[0]=i+1;
32                 continue;
33                 //如果不加continue:Input:    [0,4,3,0], 0  Output:    1, 1   Expected:    1, 4
34             }
35             if(numbers[i]==ret[1])
36             {
37                 ret[1]=i+1;
38             }
39             即使这样也不对,因为如果ret[1]出现在ret[0]后边,那么程序就错啦
40             */
41             if(numbers[i]==ret[0]||numbers[i]==ret[1])//感觉不太对吧,题上没有说元素互不相等的
42             {
43                 ret[j]=i+1;
44                 j++;
45             }
46         }
47         if(ret[0]>ret[1])
48         {
49             int t;
50             t=ret[0];
51             ret[0]=ret[1];
52             ret[1]=t;
53         }
54         return ret;
55     }
56 };

 

暴力——超时

 1 class Solution {
 2 public:
 3     vector<int> twoSum(vector<int> &numbers, int target) {
 4         vector<int> ret(2,0);
 5         int n=numbers.size();
 6         int i,j,t;
 7         for(i=0;i<n;++i)
 8         {
 9             t=target-numbers[i];
10             for(j=i+1;j<n;++j)
11             {
12                 if(numbers[j]==t)
13                 {
14                     ret[0]=i+1;
15                     ret[1]=j+1;
16                     return ret;
17                 }
18             }
19         }
20         return ret;
21     }
22 };
View Code

 

刚开始提到的解法时间复杂度O(nlgn),空间复杂度O(n),《编程之美》上有说O(nlgn)的,空间复杂度O(1)的,就是不用另外开辟数组了,和暴力解法差不多,区别就是先排序,再二分查找O(lgn),n个元素就是O(nlgn)了,书中给出的第三种解法比较好,但是不能直接用在本题中,因为题上没说数组有序,数组排序之后,下标就变化了。

这个的解决办法是自己重新构造一个数据结构,每个元素可以存放原来的下标和对应的值,然后按值排序就可以了。

 

 1 typedef struct node{
 2     int index;
 3     int value;
 4     node(){}
 5     node(int i,int v):index(i),value(v){}//C++的这种初始化方式真奇怪,在Java中我都没有见过这么写的
 6 }Node;
 7 bool cmp(const Node &a,const Node &b)
 8 {
 9     return a.value<b.value;
10 }
11 class Solution {
12 public:
13     /*
14     typedef struct node{
15         int index;
16         int value;
17         node(){}
18         node(int i,int v):index(i),value(v){}//C++的这种初始化方式真奇怪,在Java中我都没有见过这么写的
19     }Node;
20     bool cmp(const Node &a,const Node &b)
21     {
22         return a.value<b.value;
23     }
24     */
25     vector<int> twoSum(vector<int> &numbers, int target) {
26         vector<int> ret(2,0);
27         int n=numbers.size();
28         int i,j;
29         
30         vector<Node> num(n);
31         for(i=0;i<n;++i){
32             //num[i].index=i;
33             //num[i].value=numbers[i];
34             num[i]=node(i,numbers[i]);
35         }
36         //voctor sort 参看:http://www.cppblog.com/mzty/archive/2005/12/15/1770.html
37         //sort(num.begin(),num.end(),cmp); //这句错了,参看http://www.cnblogs.com/qianye/p/3316028.html
38         //呃,好吧,应该把cmp函数写到类的外面去
39         sort(num.begin(),num.end(),cmp);
40         i=0,j=n-1;
41         while(i<j)
42         {
43             if(num[i].value+num[j].value==target)
44             {
45                 ret[0]=min(num[i].index,num[j].index)+1;//根据题目要求,不要忘记了+1
46                 ret[1]=max(num[i].index,num[j].index)+1;
47             }
48             else if(num[i].value+num[j].value<target)
49             {
50                 i++;
51             }
52             else
53             {
54                 j--;
55             }
56         }
57         return ret;
58     }
59 };

应该就是这样了,不过没有AC,显示的是

 

Status: 

Time Limit Exceeded

posted on 2014-03-11 14:42  crane_practice  阅读(223)  评论(0编辑  收藏  举报

导航