已经很长一段时间没有写代码了,把很多基础的东西都忘记了。这两天打算刷一些简单的题目,先把基础的语法、概念顺一下,才能更进一步。其实核心的确实是算法以及数据结构。有针对这道题目的,也有一些C++的语法的补充内容,主要是为自己记录。方法一:暴力法 ;方法二:使用哈希表,减少时间复杂度;方法三:把方法二修改为只使用一个for循环。
两数之和的问题
方法一:暴力法
- C++指向数组的指针,一旦把第一个元素的地址存储在p中,就可以使用*p、*(p+1)、*(p+2) 等来访问数组元素。
- C++不允许返回一个完整的数组作为函数的参数。但是可以通过指定不带索引的数组名来返回一个指向数组的指针。要声明一个返回指针的函数,在函数内部定义局部变量为static变量。
int* twoSum1(int* nums, int numsSize, int target){
static int a[2]={0};
for(int i=0;i<numsSize-1;i++)
{
for(int j=i+1;j<numsSize;j++)
if(nums[i]+nums[j]==target)
{
a[0]=i;
a[1]=j;
return a;
}
}
return 0;
}
关于C++的vector,它是一个能够存放任意类型的动态数组,访问元素的方式是和数组类似的;vector可以作为函数的返回类型;但好像也不能作为形参,这点和数组是一样的。
vector<int> twoSum(vector<int>& nums, int target){
vector<int> result;
for(int i=0;i<nums.size()-1;i++)
{
for(int j=i+1;j<nums.size();j++)
{
if(nums[i]+nums[j]==target)
{
result.push_back(i);
result.push_back(j);
return result;
}
}
}
}
方法二:哈希表的构建是为了将查找时间从O(n)降到O(1)。
map是STL的一个关联容器,它提供一对一的hash。第一个是关键字key,关键字只能出现一次,第二个是该关键字的值value。
count()返回值为1或者0。该题中,m[2]=0 m[7]=1 m[11]=3 m[15]=4,关键字是2 7 11 15这些。Searches the container for elements with a key equivalent to k and returns the number of matches。HashMap是的key是不能重复的,如果有相同的key,最后一个key对应的value会把前一个相同的value覆盖掉。
map内部是红黑树,在插入元素时会自动排序,而无序容器unordered_map内部是散列表,通过哈希而不是排序来快速操作元素,使得效率更高。当你不需要排序时选择unordered_map的效率更高。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
vector<int> res;
for (int i = 0; i < nums.size(); ++i) {
m[nums[i]] = i;
}
for (int i = 0; i < nums.size(); ++i) {
int t = target - nums[i];
if (m.count(t) && m[t] != i) {
res.push_back(i);
res.push_back(m[t]);
break;
}
}
return res;
}
};
方法三:试着按上面的代码进行了修改,刚开始[3 3] 6这个测试用例无法通过,应改为先进行查找再把这个元素放入map。
class Solution {
public:
vector<int> twoSum(vector<int>& nums,int target){
unordered_map<int,int> m;
vector<int> res;
for(int i=0;i<nums.size();i++){
int t=target-nums[i];
if(m.count(t)){
res.push_back(m[t]);
res.push_back(i);
return res;
}
m[nums[i]]=i;
}
return res;
}
};