leetcode 1 two sum

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() 清空所有元素
可以直接进行赋值和比较:=, >, >=, <, <=, != 等等


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值