一、题目介绍

1.题目描述

->给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值的那两个整数,并返回它们的数组下标。

->你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

->你可以按任意顺序返回答案。

2.题目提示

->2 <= nums.length <= 103

->-109 <= nums[i] <= 109

->-109 <= target <= 109

->只会存在一个有效答案

3.演示案例

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

输入:nums = [3,3], target = 6

输出:[0,1]


二、题目分析

1.输入输出分析

整数数组nums 整数目标值target ---------->符合条件整数的下标组成的数组

2.要求分析

->由于题目描述中可以按任意顺序返回答案,所以[0,1]与[1,0]等价。

->同一元素不能用两次:数组中可能含有重复的数字,但是这些重复的数字的下标不同,所以他们属于不同的元素,这点得注意,如演示实例二。

->题目假设答案唯一,也就是说不需要找到所有的答案,只要找到一个答案就可以输出,如果写了一个函数已经找出了答案,还往下寻找,就会增加程序的执行时间。


三、解法一:穷举式寻找

1.算法理解

->穷举算法适用于所有寻找类型的问题,自己体会一下穷举在下面应用场景的不同之处:

场景1:老师让你从一年级一班里找出一个年龄在7岁以上的同学。

场景2:老师让你从一年级一班里找出所有年龄在7岁以上的同学。

场景3:老师让你从一年级一班里找出两个年龄和为15岁的两个人,用来参加这次的二人乒乓比赛。

场景4:老师让你从一年级一班里找出两个年龄和为15岁的两个人的所有配对方式,然后通过综合筛选出一对,用来参加这次的二人乒乓比赛。

->可以看见,穷举的基本过程可以描述为:对目标群体进行遍历,对于遍历所得到的目标进行筛选判断,进而筛选出满足条件的目标。

要注意的是,其中的遍历,可以根据目标群体的类型,分为一次遍历,二次遍历等等,要明白,遍历的目的只是为了得到可以用来被判断的目标。

->显然本题的场景跟场景3是相似的。

2.C++语法基础

2.1数组

->原谅我python看习惯了,竟然一开始下意识把C++的数组的括号用成了中括号,写成了int arr =[1,2,3],真是一点都不会C++啊。。。

->好像Leecode的数组用的都是vector,就是一个可以存放任何类型数据的一个动态数组,并且这个动态数组还有一些函数可以使用,如以下函数:

pop_back() //用于删除动态数组的最后一个元素。

push_back() //用于在动态数组尾部添加新的值。

empty() //用于判断数组是否为空,如果为空返回1;反之返回0。

size() //用于返回数组中元素的个数。

->创建容器方式

#include <vector>  //Leecode里自带C++的标准库,不需要导入。
vector<type>var;

2.2&与*

->*后跟指针型变量表示该指针所对应的数值,如int *p

->&后跟非指针型变量表示该变量的地址,如 p =&var

->一个脑残的代码示范:

int *p;
int a =100;
int b =200;
&a =&b; //这行是错误的,对于一个变量来说,变量值是可以修改的,但是变量的地址是不能修改的。
p =&b; /**这行是正确的,p虽然表示的是内存地址,但是它所表示的内存地址就是它这个指针型变量对应的值是没有问题的,指针只是一个特殊的变
量,它也有自己的内存地址,只不过它所对应的值刚好也是内存地址。**/
&p =&b; //这一行也是错误的,因为指针变量的地址不可以被修改,任何变量的地址都不能被修改。

->C++中&的另一个作用----引用

声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元,这就是为什么函数里的参数多是引用,可以节省空间的开销,还可以直接通过形参的改变进而改变实参,如

void swap(int &p1, int &p2) //此处函数的形参p1, p2都是引用
{ int p; p=p1; p1=p2; p2=p; }

3.我的题解

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

四、解法二:利用哈希表优化穷举的时间开销

1.算法理解

->本质上还是穷举的思路,但是在寻找的过程中,通过哈希表的数据结构将查找时间O(n)变成了O(1)。因为正常情况下从一个数组中找到自己想要找到所有的元素需要对数组里的所有元素都进行一次判断,但是从哈希表中找到一个自己想要的元素,直接就找到了,因为哈希表中所有元素的地址都是通过哈希算法根据元素名算出来的,也就是说增加了存储消耗,但是优化了查找效率。

->对于循环遍历的理解:

正常情况下,我们对一个数组的遍历是array[0],array[1],array[2],array[3].....

我们也可以反向遍历array[n-1],array[n-2],array[n-3],array[n-4]....其中n为数组中元素的个数

所以一个二次遍历共有四种遍历方式:

第一次从起点正向遍历,第二次从第一次循环的初始点正向遍历。

第一次从起点正向遍历,第二次从第一次循环的初始点反向遍历。

第一次从末尾反向遍历,第二次从第一次循环的初始点正向遍历。

第一次从末尾反向遍历,第二次从第一次循环的初始点反向遍历。

这有什么好处呢?在特殊情况下,可以减少代码的编写量。

->这里我的算法思路是

第一次从起点正向遍历,代码如下:

for(int i=0;i<nums.size();i++){code}

第二次从初始点反向遍历,代码如下:

for(int s=i-1;i>=0;i--){code}   //因为题目中同一个元素不能跟自己所匹配,所以起点从i往左移动一个位置,使之跟自己前面的所有元素进行累加确定值是否为target

把上面的二次遍历优化为哈希表,索引为i的元素跟自己之前的所有元素进行匹配可以看做是跟哈希表进行匹配,每一次迭代中,如果哈希表找不到元素,就将哈希表向右边扩充一个pair,代码如下:

auto ii =hashmap.find(target-nums[i]); //这里auto是C++11新标准,申明变量后自动确定该变量对应的类型。
if(ii!=hashmap.end()){
return {i,ii->second};
}
hashmap.insert(make_pair(nums[i],i));

2.C++算法基础

2.1C++ 中的 ::

https://blog.csdn.net/qq1623803207/article/details/89398435

2.2C++ 中的unordered_map

->首先说一下,C++11在std中定义了很多容器,这些容器的效率非常高,根本没有必要自己去定义数据结构,这里的unordered_map就是一种类似于哈希表的容器,它的作用就是优化查找效率,而vector容器的作用就相当于于动态数组,我真的是爱死C++了,本来以为C++中的库很垃圾,跟python根本没法比,但是现在才发现C++真的十分优美,高效,简洁。这里unordered_map的头文件为<unordered_map>,注意跟vector容器一样,在leecode里这些头文件都默认已经有过了。

->unordered_map的迭代器是一个指针,指向这个元素,通过迭代器来取得它的值,就相当于数组里的索引i一样,初始迭代器就是i=0,末尾迭代器就是i=array.size()。

1 it->first;               // same as (*it).first   (the key value)
2 it->second; // same as (*it).second (the mapped value)

->成员函数

begin    返回指向容器起始位置的迭代器

end    返回指向容器末尾位置的迭代器 ,该迭代器指向unordered_map容器中最后一个元素之后的位置

size    返回有效元素个数

empty 判断是否为空,如果为空;返回1,非空返回0

find 如果key存在,则find返回key对应的迭代器,如果key不存在,则find返回unordered_map::end。可以通过map.find(key) == map.end()来确定key是否存在于unordered_map中。

insert 插入键值对,至于如何获得键值对,可以使用std::make_pair函数获得。

3.我的题解

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> hashmap;
for(int i=0;i<nums.size();++i){
auto ii =hashmap.find(target-nums[i]);
if(ii!=hashmap.end()){
return {ii->second,i};
}
hashmap.insert(make_pair(nums[i],i));
}
return {}; }
};

C++_Leecode1 两数之和的更多相关文章

  1. 给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X

    题目:给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X 思路一: 1,先采用归并排序对这个数组排序, 2,然后寻找相邻<k,i>的两数之和sum,找到恰好sum>x的 ...

  2. LeetCode 170. Two Sum III - Data structure design (两数之和之三 - 数据结构设计)$

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

  3. LeetCode 371. Sum of Two Integers (两数之和)

    Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. Exam ...

  4. LeetCode 167. Two Sum II - Input array is sorted (两数之和之二 - 输入的是有序数组)

    Given an array of integers that is already sorted in ascending order, find two numbers such that the ...

  5. [LeetCode] Two Sum IV - Input is a BST 两数之和之四 - 输入是二叉搜索树

    Given a Binary Search Tree and a target number, return true if there exist two elements in the BST s ...

  6. [LeetCode] 1. Two Sum 两数之和

    Part 1. 题目描述 (easy) Given an array of integers, return indices of the two numbers such that they add ...

  7. Leetcode(一)两数之和

    1.两数之和 题目要求: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重 ...

  8. 南大算法设计与分析课程OJ答案代码(1)中位数附近2k+1个数、任意两数之和是否等于给定数

    问题1 用来测试的,就不说了 问题2:中位数附近2k+1个数 给出一串整型数 a1,a2,...,an 以及一个较小的常数 k,找出这串数的中位数 m 和最接近 m 的小于等于 m 的 k 个数,以及 ...

  9. 两数之和,两数相加(leetcode)

    我们都知道算法是程序员成长重要的一环,怎么才能提高算法呢, 出来在网上看视频之外,动手练习是非常重要的.leetcode 就是一个非常好的锻炼平台. 1. 两数之和,在 leetcode 里面是属于 ...

随机推荐

  1. Codeforces Round #742 (Div. 2)

    A. Domino Disaster 思路 按照题意模拟即可 如果是 对应关系为R --> R L --> L U --> D D --> U AC_CODE inline v ...

  2. ApacheCN Pandas 教程集

    Pandas 秘籍 零.前言 一.Pandas 基础 二.数据帧基本操作 三.开始数据分析 四.选择数据子集 五.布尔索引 六.索引对齐 七.分组以进行汇总,过滤和转换 八.将数据重组为整齐的表格 九 ...

  3. 「JOI 2014 Final」飞天鼠

    「JOI 2014 Final」飞天鼠 显然向上爬是没有必要的,除非会下降到地面以下,才提高到刚好为0. 到达一个点有两种情况:到达高度为0和不为0. 对于高度不为0的情况,显然花费的时间越少高度越高 ...

  4. 「JOISC 2016 Day 1」棋盘游戏

    「JOISC 2016 Day 1」棋盘游戏 先判无解:第1,3行有连续的空格或四个角有空格. 然后可以发现有解的情况第1,3行可以在任意时间摆放. 对于某一列,若第2行放有棋子,那么显然可以把棋盘分 ...

  5. 在Excel VBA中使用SQL到底优势在哪儿

    小爬在之前的博文中多次提到,可以在VBA中写SQL来操作Excel文件,实现各类数据处理和分析需求.那么,你可能有这样的疑问:Excel原生的VBA,数据透视表,数据分析功能不够吗,为啥一定要用SQL ...

  6. LeetCode随缘刷题之最短补全词

    package leetcode.day_12_10; import org.junit.Test; /** * 给你一个字符串 licensePlate 和一个字符串数组 words ,请你找出并返 ...

  7. JTAG 标准IEEE STD 1149.1-2013学习笔记(一·)Test logic architecture、Instruction register以及Test data registers

    我是 雪天鱼,一名FPGA爱好者,研究方向是FPGA架构探索和SOC设计. 关注公众号[集成电路设计教程],拉你进"IC设计交流群". 注:转载请注明出处 一.Test logic ...

  8. 2022年了有哪些值得推荐的.NET ORM框架?

    前言: 最近有很多同学问我.NET方面有哪些好用的ORM框架,我觉得这方面的介绍网上应该会介绍的比较全面文章,于是我想搜一篇全面的介绍文章发给他们结果我发现网上说来说去基本上就是那几个,于是就有了这篇 ...

  9. Spring常用配置使用示例

    上篇介绍了Spring配置的基本情况,本篇介绍Spring常用配置具体如何使用.关于基础的配置,比如Configuration之类的就不示例,主要示例相对用的比较多同时可能比较复杂的标签或属性. 1) ...

  10. Golang Sync.WaitGroup 使用及原理

    Golang Sync.WaitGroup 使用及原理 使用 func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.A ...