2 Sum
Problem
Given an array of integers, find two numbers such that they add up to aspecific target number. The function twoSum should return indices of the two numbers such thatthey add up to the target, where index1 must be less than index2. Please notethat your returned answers (both index1 and index2) are NOT zero-based. Example
numbers=[, , , ], target= return [, ] Note
You may assume that each input would have exactly one solution Challenge
Either of the following solutions are acceptable: O(n) Space, O(nlogn) Time
O(n) Space, O(n) Time
题解1 - 哈希表
找两数之和是否为target
, 如果是找数组中一个值为target
该多好啊!遍历一次就知道了,我只想说,too naive... 难道要将数组中所有元素的两两组合都求出来与target
比较吗?时间复杂度显然为 O(n2), 显然不符题目要求。找一个数时直接遍历即可,那么可不可以将两个数之和转换为找一个数呢?我们先来看看两数之和为target
所对应的判断条件—— xi+xj=target, 可进一步转化为 xi=target−xj, 其中 i 和 j 为数组中的下标。一段神奇的数学推理就将找两数之和转化为了找一个数是否在数组中了!可见数学是多么的重要...
基本思路有了,现在就来看看怎么实现,显然我们需要额外的空间(也就是哈希表)来保存已经处理过的 xj(注意这里并不能先初始化哈希表,否则无法排除两个相同的元素相加为 target 的情况), 如果不满足等式条件,那么我们就往后遍历,并把之前的元素加入到哈希表中,如果target
减去当前索引后的值在哈希表中找到了,那么就将哈希表中相应的索引返回,大功告成!
C++:
class Solution {
public:
/*
* @param numbers : An array of Integer
* @param target : target = numbers[index1] + numbers[index2]
* @return : [index1+1, index2+1] (index1 < index2)
*/
vector<int> twoSum(vector<int> &nums, int target) {
vector<int> result;
const int length = nums.size();
if ( == length) {
return result;
} // first value, second index
unordered_map<int, int> hash(length);
for (int i = ; i != length; ++i) {
if (hash.find(target - nums[i]) != hash.end()) {
result.push_back(hash[target - nums[i]]);
result.push_back(i + );
return result;
} else {
hash[nums[i]] = i + ;
}
} return result;
}
};
JAVA:
public class Solution {
/*
* @param numbers : An array of Integer
* @param target : target = numbers[index1] + numbers[index2]
* @return : [index1 + 1, index2 + 1] (index1 < index2)
*/
public int[] twoSum(int[] numbers, int target) {
if (numbers == null || numbers.length == 0) return new int[]{0, 0}; Map<Integer, Integer> hashmap = new HashMap<Integer, Integer>();
int index1 = 0, index2 = 0;
for (int i = 0; i < numbers.length; i++) {
if (hashmap.containsKey(target - numbers[i])) {
index1 = hashmap.get(target - numbers[i]);
index2 = i;
return new int[]{1 + index1, 1 + index2};
} else {
hashmap.put(numbers[i], i);
}
} return new int[]{0, 0};
}
}
源码分析
- 异常处理。
- 使用 C++ 11 中的哈希表实现
unordered_map
映射值和索引。Python 中的dict
就是天然的哈希表。 - 找到满足条件的解就返回,找不到就加入哈希表中。注意题中要求返回索引值的含义。
复杂度分析
哈希表用了和数组等长的空间,空间复杂度为 O(n), 遍历一次数组,时间复杂度为 O(n).
题解2 - 排序后使用两根指针
但凡可以用空间换时间的做法,往往也可以使用时间换空间。另外一个容易想到的思路就是先对数组排序,然后使用两根指针分别指向首尾元素,逐步向中间靠拢,直至找到满足条件的索引为止。
C++:
class Solution {
public:
/*
* @param numbers : An array of Integer
* @param target : target = numbers[index1] + numbers[index2]
* @return : [index1+1, index2+1] (index1 < index2)
*/
vector<int> twoSum(vector<int> &nums, int target) {
vector<int> result;
const int length = nums.size();
if ( == length) {
return result;
} // first num, second is index
vector<pair<int, int> > num_index(length);
// map num value and index
for (int i = ; i != length; ++i) {
num_index[i].first = nums[i];
num_index[i].second = i + ;
} sort(num_index.begin(), num_index.end());
int start = , end = length - ;
while (start < end) {
if (num_index[start].first + num_index[end].first > target) {
--end;
} else if(num_index[start].first + num_index[end].first == target) {
int min_index = min(num_index[start].second, num_index[end].second);
int max_index = max(num_index[start].second, num_index[end].second);
result.push_back(min_index);
result.push_back(max_index);
return result;
} else {
++start;
}
} return result;
}
};
源码分析
- 异常处理。
- 使用
length
保存数组的长度,避免反复调用nums.size()
造成性能损失。 - 使用
pair
组合排序前的值和索引,避免排序后找不到原有索引信息。 - 使用标准库函数排序。
- 两根指针指头尾,逐步靠拢。
复杂度分析
遍历一次原数组得到pair
类型的新数组,时间复杂度为 O(n), 空间复杂度也为 O(n). 标准库中的排序方法时间复杂度近似为 O(nlogn), 两根指针遍历数组时间复杂度为 O(n).
2 Sum的更多相关文章
- LeetCode - Two Sum
Two Sum 題目連結 官網題目說明: 解法: 從給定的一組值內找出第一組兩數相加剛好等於給定的目標值,暴力解很簡單(只會這樣= =),兩個迴圈,只要找到相加的值就跳出. /// <summa ...
- Leetcode 笔记 113 - Path Sum II
题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...
- Leetcode 笔记 112 - Path Sum
题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...
- POJ 2739. Sum of Consecutive Prime Numbers
Sum of Consecutive Prime Numbers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 20050 ...
- BZOJ 3944 Sum
题目链接:Sum 嗯--不要在意--我发这篇博客只是为了保存一下杜教筛的板子的-- 你说你不会杜教筛?有一篇博客写的很好,看完应该就会了-- 这道题就是杜教筛板子题,也没什么好讲的-- 下面贴代码(不 ...
- [LeetCode] Path Sum III 二叉树的路径和之三
You are given a binary tree in which each node contains an integer value. Find the number of paths t ...
- [LeetCode] Partition Equal Subset Sum 相同子集和分割
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...
- [LeetCode] Split Array Largest Sum 分割数组的最大值
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- [LeetCode] Sum of Left Leaves 左子叶之和
Find the sum of all left leaves in a given binary tree. Example: 3 / \ 9 20 / \ 15 7 There are two l ...
- [LeetCode] Combination Sum IV 组合之和之四
Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...
随机推荐
- Struts第三天
OgnlValueStack贯穿整个 Action 的生命周期. 它是ContextMap中的一部分,里面的结构是一个List,是我们可以快速访问数据一个容器.它的封装是由struts2框架完成的. ...
- Zbar和Z*算法对比
博客转载自:https://blog.csdn.net/qishandaxue/article/details/45481387 移植zbar和zxing源码到linux平台,zbar移植的是C源码, ...
- PCL —— RCNN Family 中层次点云处理
博客转载自:http://www.cnblogs.com/ironstark/p/6046411.html RCNN是从图像中检测物体位置的方法,严格来讲不属于三维计算机视觉.但是这种方法却又非常非常 ...
- JavaPersistenceWithHibernate第二版笔记-第七章-003Mapping an identifier bag(@OrderColumn、@ElementCollection、@CollectionTable、、)
一.结构 二.代码 1. package org.jpwh.model.collections.listofstrings; import org.jpwh.model.Constants; impo ...
- 使用paramiko连接EC2主机
在亚马逊云上建的主机没有密码,只有一个PEM文件.所以paramiko需要通过该PEM文件登录云主机进行管理 有两种方式,第一种被我注解了 import paramiko ssh = paramiko ...
- Newtonsoft Json操作类库的使用
1.解析简单Json字符串 if (l_sSenJson != "") { JObject obj2 = (JObject)JsonConvert.DeserializeObjec ...
- Required plugin could not be found. Videos requires to install plugins to play files of the following types : MPEG-4-AAC decoder and H.264 decoder
https://linuxconfig.org/how-to-install-mpeg-4-aac-decoder-for-centos-7-linux 记得联网情况下才能下载.
- 循环中标签outer用法:break outer continue outer
1.outer: break 如果不使用标签,break跳出里层for循环,使用break标签,则跳出两层循环 输出:i:0 j:0 i:0 j:1 public class breakTest { ...
- C++工程实践 一个开始
打算把C++工程过程中的一些总结写下来.从打算写这个内容到今天(2017/1/12)已经很多年了,但是一直没有想好如何写,反正就这样,有什么写什么吧. C++工程实践之所以难产,主要原因有几个 内容比 ...
- 原来腾讯安全中心TP和虚拟机vmware10是有冲突的
用VMware 10启动linux,总是出现VMware Workstation 不可恢复错误: (vmx)... 然后网上查了好多类似问题始终不能解决.后来发现每次出现这个问题腾讯的TP是启动的 ...