leetcode 1 two sum
本文给出leetcode第一题Two Sum的答案及所用到的简单知识总结,适用于C++初学者
本文代码下载地址
目录
题目
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums1 = 2 + 7 = 9,
return [0, 1].
暴力枚举法
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans;
for(int i=0;i<nums.size();i++){
for(int j=i+1;j<nums.size();j++){
if (target - nums[i] == nums[j]){
ans.push_back(i);
ans.push_back(j);
return ans;
}
}
}
return ans;
}
};
int main(){
Solution t;
vector<int> test;
int target = 0;
test.push_back(0); test.push_back(7);
test.push_back(11); test.push_back(0);
cout << t.twoSum(test, target)[0] << " " << t.twoSum(test, target)[1] << endl;
system("pause");
}
这是最容易想到的方法,按照顺序循环的方式从所给vector中的第一个元素开始,查找在后续元素中是否存在元素与之相加等于target。此方法时间复杂度为O(n^2)。
因leetcode中预设的提交格式为以vector和int型变量作为输入,返回vector的函数,所以我们也按照这样的格式进行编写。提交leetcode代码时,只需要提交Solution类即可。main()函数主要是为了在visual studio中测试方便。
应用map类的方法
#include<iostream>
#include<vector>
#include<map>
using namespace std;
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> My_map;
vector<int> ans;
for(int i=0;i<nums.size();i++){
My_map.insert(pair<int,int>(nums[i],i));
}
for(int i=0;i<nums.size();i++){
if(My_map.count(target-nums[i]) && My_map.find(target-nums[i])->second != i){
ans.push_back(My_map.find(target-nums[i])->second < i ? My_map.find(target-nums[i])->second : i);
ans.push_back(My_map.find(target-nums[i])->second > i ? My_map.find(target-nums[i])->second : i);
return ans;
}
}
return ans;
}
};
int main(){
Solution t;
vector<int> test;
int target = 0;
test.push_back(0); test.push_back(7);
test.push_back(11); test.push_back(0);
cout << t.twoSum(test, target)[0] << " " << t.twoSum(test, target)[1] << endl;
system("pause");
}
这种方法的主要思想是从vector中的第一个元素开始循环,计算target-vector[i]的值是否在剩余元素中。因为使用map进行查找操作比较方便,因此我们在这里使用map类。我们将输入的vector中的数字作为key值,将数字下标作为value值进行存储。
对vector中的每个元素进行循环,首先使用语句 My_map.count(target-nums[i]) 判断 map 中是否存在键值 target-nums[i] 。而后判断该键值所指向的 value 值是否等于 nums[i] 的下标 i,这样做是为了确保不会出现当输入数据中 nums[i] 的值没有重复出现,但却有 nums[i] + nums[i] 等于 target 的情况出现。
此处值得注意的是, map 中同一个键值只能出现一次。如果输入 vector 中包含两个或两个以上相同的数字,那么在将他们映射到 map 中时,该键值对应的value值为第一个数字的下标。
在程序中之所以使用 ?: 运算符是为了确保输出一定是按从大到小的顺序排列的。如果我们将语句
ans.push_back(My_map.find(target-nums[i])->second < i ? My_map.find(target-nums[i])->second : i);
ans.push_back(My_map.find(target-nums[i])->second > i ? My_map.find(target-nums[i])->second : i);
改为ans.push_back(i); ans.push_back(My_map.find(target-nums[i])->second);
在测试样例 [0, 4, 7, 0] target=0 时就会输出 [3, 0], 与期望输出 [0, 3]不符。
C++中vector的简单操作
此处转载Happy Working的博客,只写出基本操作:
1 基本操作
(1)头文件#include<vector>.
(2)创建vector对象,vector <int> vec
(3)尾部插入数字:vec.push_back(a);
(4)使用下标访问元素,cout << vec[0] << endl;
记住下标是从0开始的。
(5)使用迭代器访问元素.
vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
cout<<*it<<endl;
(6)插入元素: vec.insert(vec.begin()+i,a);
在第i+1个元素前面插入a;
(7)删除元素: vec.erase(vec.begin()+2);
删除第3个元素
vec.erase(vec.begin()+i,vec.end()+j);
删除区间[i,j-1];区间从0开始
(8)向量大小:vec.size();
(9)清空:vec.clear();
C++中map的简单操作
此处转载ANYWEI : CODING的博客,
1 头文件 #include <map>
2 定义 map<string, int> my_Map;
或者是typedef map<string, int> MY_MAP; MY_MAP my_Map;
3 插入数据
(1) my_Map["a"] = 1;
(2) my_Map.insert(map<string, int>::value_type("b",2));
(3) my_Map.insert(pair<string,int>("c",3));
(4) my_Map.insert(make_pair<string,int>("d",4));
4 查找数据和修改数据
(1) int i = my_Map["a"];
my_Map["a"] = i;
(2) MY_MAP::iterator my_Itr;
my_Itr.find("b");
int j = my_Itr->second;
my_Itr->second = j;
不过注意,键本身是不能被修改的,除非删除。
5 删除数据
(1) my_Map.erase(my_Itr);
(2) my_Map.erase("c");
还是注意,第一种情况在迭代期间是不能被删除的,道理和foreach时不能删除元素一样。
6 迭代数据
for (my_Itr=my_Map.begin(); my_Itr!=my_Map.end(); ++my_Itr) {}
7 其它方法
my_Map.size() 返回元素数目
my_Map.empty() 判断是否为空
my_Map.clear() 清空所有元素
可以直接进行赋值和比较:=, >, >=, <, <=, != 等等