讲解LeetCode第1题:两数之和(完整代码)

题目介绍:

输入:nums={2,7,11,15} , target=22

输出:1,3

解释:因为num[1]+num[3]==22 , 所以返回1,3

方法一:暴力枚举

完整代码展示

#include<iostream>
#include<vector>
using namespace std;


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 {};
	}
};


int main()
{
	vector<int>nums = { 2,7,11,15 };
	int target = 22;

	Solution find;
	vector<int>result=find.twoSum(nums, target);

	if (!result.empty())
	{
		cout << "目标值" << target << "是下标为"
			<< result[0] << "和" << result[1] 
			<< "对应的值之和" << endl;
	}
	else
	{
		cout << "没有两数之和是" << target << endl;
	}
	return 0;
}

核心原理演示

输入:nums={2,7,11,15} , target=22

在这里插入图片描述

输出:1,3

代码片段解释

片段一:

#include<iostream>
#include<vector>

iostream库是C++标准库的一个头文件,他提供了进行输入和输出操作的类。例如:输入类 istream和输出类ostream。我们在C++使用的cin和cout就是这些类的实例化对象。

vector容器类是C++标准模板库 (STL)的一个头文件,它提供了一种能够存储任意类型的动态数组的容器。

总而言之:这两行代码通过包含C++标准库中的iostream和vector头文件,使得你的程序能够使用输入输出流动态数组的功能。

注:与C语言中的数组不同,vector的大小可以在运行时改变,他会自动管理其存储的内存。

片段二:

return{ i,j };
return {};

这两句代码使用了C++11引入的列表初始化语法:它允许你直接在返回语句中初始化一个对象。

例如:return{i,j};中就创建一个临时vector对象,并用i和j作为它的初始化元素。

即,在C++11中,当你使用花括号{}包围一系列值时,并且这些值被用于需要特定类型对象的上下文中(比如函数的返回类型),编译器会自动进行类型推导对象初始化

片段三:

int n = nums.size();
if (!result.empty())

这两句代码中nums和result都是vector容器类实例化的对象,这里这两个对象分别调用了不同的成员函数。

  • 成员函数size(), 该函数返回容器中元素的数量。

  • 成员函数empty(), 该函数返回一个布尔值,判断容器是否为空。如果为空返回true,否则返回false。

注:这两个成员函数不仅适用于vector容器,还适用于list容器。

方法二:哈希表

完整代码展示

#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;


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


int main()
{
	vector<int>nums = { 6,3,8,2,1 };
	int target = 8;

	Solution find;
	vector<int>result = find.twoSum(nums, target);

	if (!result.empty())
	{
		cout << "目标值" << target << "是下标为"
			<< result[0] << "和" << result[1]
			<< "对应的值之和" << endl;
	}
	else
	{
		cout << "没有两数之和是" << target << endl;
	}
	return 0;
}

核心原理演示

输入:nums={6,3,8,2,1} , target=8

在这里插入图片描述

输出:0,3

代码片段解释

片段一:

#include<unordered_map>
unordered_map<int, int>hashtable;

与vector同样unordered_map也是C++标准模板库的一个头文件。

vector定义了一个序列容器,unordered_map定义了一个 关联容器

unorder_map存储的元素是键值对(key-value pairs),其中每一个键都是唯一的,并且映射到一个值。

因此unordered_map<int, int>hashtable;创建了一个unorder_map<int,int>类型的关联容器hashtable,用以存储数组nums中的元素值作为键(key),以及这些元素在数组中的索引作为值(value)。

片段二:

auto it = hashtable.find(target - nums[i]);
if (it != hashtable.end())

这两句代码中hashtable分别调用了unordered_map的两个成员函数。

  • 成员函数find(),该函数返回一个找到的的迭代器,作为查找的最终结果。如果找到了对应的(本例中是target - nums[i]),迭代器将指向该键对应的元素;如果没有找到,迭代器将等于一个特殊的迭代器end()。
  • 成员函数end(),该函数返回一个特殊的迭代器。它指向容器的“尾部位置”(注:这不是一个有效的元素位置,而是用作算法和成员函数的一个终止条件),所以说任何指向容器内元素的迭代器都会小于end()迭代器。

片段三:

return { it->second,i };

it->second用于访问迭代器it指向的元素的相关联的。或者可以理解为通过it->second访问迭代器it指向的元素的部分。

片段四:

hashtable[nums[i]] = i;

这行代码是在向一个名为hashtable的unorder_map容器中添加更新一个键值对。

  • 键:nums[i],是正在遍历的nums数组中的元素。
  • 值:i,是该元素在nums数组中的索引。

注意:

  • 如果hashtable中不存在键等于nums[i],那么一个新的键值对将被添加到hashtable中,键为nums[i],值为i。

  • 如果hashtable中已经存在一个键等于nums[i],那么它相关联的值将被更新为当前的i

为hashtable的unorder_map容器中添加更新一个键值对。

  • 键:nums[i],是正在遍历的nums数组中的元素。
  • 值:i,是该元素在nums数组中的索引。

注意:

  • 如果hashtable中不存在键等于nums[i],那么一个新的键值对将被添加到hashtable中,键为nums[i],值为i。

  • 如果hashtable中已经存在一个键等于nums[i],那么它相关联的值将被更新为当前的i

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值