【leetcode c++】twoSum

4月份接触leetcode,没多久就要准备考试大坑,已然忘记这玩意。最近得闲,便把已经写好的leetcode整理一下发到博客来。

(应该不会出问题吧第一次写博客→  →)

先上题目原文

Given anarray of integers, find two numbers such that they add up to a specific targetnumber.

Thefunction twoSum should return indices of the two numbers such that they add upto the target, where index1 must be less than index2. Please note that yourreturned answers (both index1 and index2) are not zero-based.

You mayassume that each input would have exactly one solution.

Input: numbers={2,7, 11, 15}, target=9
Output: 
index1=1, index2=2

题目大意:

提供一个整型数组,在数组中寻找两个数使得这两个数的和等于目标数值。

函数twoSum应该返回这两个数的下标,第一个下标应小于第二个下标,请注意下标不是基于零的(0是第一个下标)。

你可以假设所有的输入都是有唯一解的。

 

解法1:最无脑的就是嵌套循环了。此略。

 

解法2:会不会觉得嵌套循环的时间复杂度稍微高了点呢?我们再重新审视题目,简单地说题目的目的就是找到两个数的下标……两个数对应的下标……对应……key-value……对了就是关联容器。

       由于本人使用c++语言,那么就选用(multi)map了,为什么要加了个(multi)呢?我们继续探讨,是否有可能数组的的元素有重复。我们假设一种情况,Numebr={1, 1, 3, 4} target=2。这种情况下是否存在唯一解?答案是:是的。index1=1,index2=2。那么数组元素是有重复元素的可能性了,所以最终决定要使用multimap。

       既然使用了关联容器,那么肯定不能再嵌套循环了,要在一次for循环内结束战斗。在嵌套循环的做法中我们是这么做的:if(target == a + b )。能不能把b去掉,用别的已知变量代替呢?比如这样:if(target == a + (target- a) )。好吧,这样子看起来确实很愚蠢,去括号之后就变成target == target了,但是这是个很好的思路。我们换成另一个形式:

我们的multimap是以数组元素的值为键(key),以下标为值(value)的。那么看这句。

numsMap.end() !=numsMap.find(target - iterator->first)  //target – a 存在

是不是明朗起来了?

但是不要着急,再给一种情况。Numebr={1, 3, 4} target=2。会发生什么呢。会发生取了2次1的情况,因此存在解index1=1,index2=1。所以我们还要判断,这组解的两个数的下标不能相同。

if ((numsMap.end() != numsMap.find(target -iter1->first))   //存在a + b = target

       &&((numsMap.find(target - iter1->first))->second)!= iter1->second)   // 且a和b不是同一个下标

好了吗?可以交卷了吗?

请注意,返回的两个下标是升序的(where index1 must be less than index2),所以最后还要排序一下。

懒人版就是:sort(res.begin(), res.end());

 

Leetcode的AcceptedSolutions Runtime Distribution(这个截图是5月上旬截的。灰色大柱子才是真正的you are here。黄色是c++紫色是c)

 

 

源码:(VS2013)如果需要提交leetcode只需要把twoSun函数中的代码复制过去即可。

#include <vector>
#include <iostream>
#include <map>
#include <algorithm>  

using namespace std;

vector<int> twoSum(vector<int>&, int);

int main()
{
	vector<int> nums = {0,2,4,0 };
	cout << twoSum(nums, 0)[0] << " " << twoSum(nums, 0)[1];
	return 0;
}

vector<int> twoSum(vector<int>& nums, int target){
	vector<int> res;
	multimap<int, int> numsMap;
	multimap<int, int>::iterator iter1;
	int max = nums.size();

	//数组转进map,用下标做键
	for (int i = 0; i < max; i++)
	{
		numsMap.insert(pair<int, int>(nums[i], i + 1));
	}

	for (iter1 = numsMap.begin(); iter1 != numsMap.end(); iter1++){

		//map.(target-a)存在,则存在a + b = target
		//且不是本身。
		if ((numsMap.end() != numsMap.find(target - iter1->first)) &&
			((numsMap.find(target - iter1->first))->second)//第二个下标,即(target-a)
			!= iter1->second)//第一个下标,即a
		{
			//将下标存到vector,并排序
			res.push_back((iter1->second));
			res.push_back((((numsMap.find(target - iter1->first))->second)));
			sort(res.begin(), res.end());
			break;
		}
	}

	return res;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值