LeetCode学习——两数之和,C++方法(附详解,map,vector)

题目描述

  给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
  你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

解法一:暴力搜索法

 思路:

  看到题目的第一眼想到的肯定是暴力搜索方法:即使用两个for循环,在第一个循环中,检查对于第i个元素,是否存在一个位置j处在[i + 1, ],使得nums[ i ] + nums[ j ] = target。很明显,此方法的时间复杂度为O(N2),空间复杂度为O(1),只需要一个vector类型的变量来存储用于返回的结果。

 代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        for(int i = 0; i < nums.size(); i++) {
            for(int j = i + 1; j < nums.size(); j++) {
                if(target == nums[i] + nums[j]) {
                    result.push_back(i);
                    result.push_back(j);
                    return result;
                }
            }
        }
        return result;
    }
};

 vector相关用法:

  由于是第一次使用LeetCode,刚开始对于给出的模板不是很理解,甚至打开了vscode去自己写(手动捂脸),后来才知道模板中只需要给出算法即可,nums和target均已给出。
  后是关于vector的用法,此处给出一些基础用法:
  vector在C++中就是一个不定长数组,而且将 一些基本操作封装在了vector类型内部。vector也是一个模板类,需要用vector<int> a这样的方式来声明一个vector。vector<int> a是一个类似于int a[ ]的整数数组,而vector<string> a就是一个类似于string a[ ]的字符串数组。此外,vector可以直接赋值,还可以作为函数的参数或者返回值,而无需像数组那样另外用一个变量来指定元素个数。
  关于封装在vector内部的一些常用操作,有以下几个比较常用的:例如,若a是一个vector,可以有a.size()读取它的大小,a.resize()改变大小,a.push_back()向尾部添加元素,a.pop_back()删除最后一个元素。


解法二:哈希表

 思路:

  在暴力搜索中,时间复杂度达到了O(N2),空间复杂度相比较来说较小,可以说是用时间换空间的一种方法,此处考虑换一种方法来降低时间复杂度,用空间来换取时间复杂度的下降,因此选择使用哈希表,因为哈希表每次的查找近似于O(1)的复杂度,基于C++中的map来实现。
  首先对nums中的数据进行遍历,对于每一个,以其数值作为map中的key,所在位置作为map的value创建这样的哈希表。第二次对nums进行遍历,查找此哈希表中是否存在以 target - 当前数组元素值 为key的值,在此处,要排除key值等于自己的情况,因此在if判断中要用两个逻辑表达式,若找到,则在对应的result中添加这两个并返回。

 代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        for(int i = 0; i < nums.size(); i++) {
            if(nums[i] >= target) continue;
            for(int j = i + 1; j < nums.size(); j++) {
                if(target == nums[i] + nums[j]) {
                    result.push_back(i);
                    result.push_back(j);
                    return result;
                }
            }
        }
        return result;
    }
};

map相关用法简介:

  map是从键(key)到值(value)的映射。map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。在map中,可以修改value而不可以修改key。通常用map<int, string> month创建一个名为month的map,其key的数据类型为int,value的数据类型为string。
  以上述month为例,向其中插入数据,可以有以下两种方式:
  1.用insert函数插入pair数据:
    month.insert(pair<int, string>(1, “January”));
  2.以类似数组的方式添加元素:
    month[5] = “May”;
  若要查看map的大小,可以使用size函数,即:
    month.size();
  在上述代码中,我们用到了count函数,count函数的功能是判断某关键值是否在map中出现,由于map函数一对一的特点,决定其返回值只有两个,0表示map中无此key’值,而1则表示存在此key值,但是count方法无法得知此key值在map中所处的具体位置。
  若要在map中删除某一个元素,可以使用erase函数,其主要有以下几种用法:
  1. 使用迭代器删除,如下代码所示:

       map<int, string>::iterator iter;  
       iter = month.find(1);
       month.erase(iter);

  2. 以key删除:

	month.erase(1);

  3. 删除一个范围,注意此范围是一个前闭后开的范围,例如,使用如下代码可以将整个map清空:

	month.erase(month.begin(), month.end());
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值