LeetCode——Two Sum
#1
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
这题的目的是求一个整型数组中,返回两个元素的索引,这两个元素相加的和等于整型target。
- 暴力求解/C++
class Solution
{
public:
vector<int> twoSum(vector<int>& nums,int target)
{
int i,j,sum;
vector<int> results;
for(i = 0;i < nums.size() - 1;i++)
{
for(j = i + 1;j < nums.size();j++)
{
sum = nums[i] + nums[j];
if(sum == target)
{
results.push_back(i);
results.push_back(j);
}
}
}
return results;
}
};
如果用暴力求解的话,在目前的leetcode上是可以通过的,但时间复杂度比较高,但想要找到更优解的话,就要在程序上进行优化。记录下几种语言的较优解法,学习一下。
- C++解法二
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
vector<int> res;
for (int i = 0; i < nums.size(); ++i) {
m[nums[i]] = i;
}
for (int i = 0; i < nums.size(); ++i) {
int t = target - nums[i];
if (m.count(t) && m[t] != i) {
res.push_back(i);
res.push_back(m[t]);
break;
}
}
return res;
}
};
这个写法可以简化,两个for循环可以结合在一起,使用unorderd_map关联容器。
- C++解法三
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
for (int i = 0; i < nums.size(); ++i) {
if (m.count(target - nums[i])) {
return {i, m[target - nums[i]]};
}
m[nums[i]] = i;
}
return {};
}
};
unorderd_map与map类似,新版的hash_map都是unorderd_map。
unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,
存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历。
运行效率方面:unordered_map最高,而map效率较低但 提供了稳定效率和有序的序列。
占用内存方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的。需要无序容器,快速查找删除,不担心略高的内存时用unordered_map;有序容器稳定查找删除效率,内存很在意时候用map。
上面的两种解法都是比较灵活的,还有一种相对暴力解法比较相似的写法,也记录一下吧。
- C++解法四
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
int i, sum;
vector<int> results;
map<int, int> hmap;
for(i=0; i<numbers.size(); i++){
if(!hmap.count(numbers[i])){
hmap.insert(pair<int, int>(numbers[i], i));
}
if(hmap.count(target-numbers[i])){
int n=hmap[target-numbers[i]];
if(n<i){
results.push_back(n+1);
results.push_back(i+1);
//cout<<n+1<<", "<<i+1<<endl;
return results;
}
}
}
return results;
}
};
- Java
public class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> m = new HashMap<Integer, Integer>();
int[] res = new int[2];
for (int i = 0; i < nums.length; ++i) {
if (m.containsKey(target - nums[i])) {
res[0] = i;
res[1] = m.get(target - nums[i]);
break;
}
m.put(nums[i], i);
}
return res;
}
}
也是使用hashmap的操作,使得时间复杂度降低为o(n)。
- Java解法二
public int[] twoSum(int[] numbers, int target) {
int[] res = new int[2];
if(numbers==null || numbers.length<2)
return null;
Arrays.sort(numbers);
int l = 0;
int r = numbers.length-1;
while(l<r)
{
if(numbers[l]+numbers[r]==target)
{
res[0] = number[l];
res[1] = number[r];
return res;
}
else if(numbers[l]+numbers[r]>target)
{
r--;
}
else
{
l++;
}
}
return null;
}
这里使用了先对数组排序,再夹逼的方法找出满足要求的一对数。注意这里的输出是两个数,而不是两个数的序列。如果要得到序列,还需要另外的操作,这么一来其实是比解法一麻烦一点。
- Python
class Solution:
# @return a tuple, (index1, index2)
def twoSum(self, num, target):
dict = {}
for i in xrange(len(num)):
x = num[i]
if target-x in dict:
return (dict[target-x]+1, i+1)
dict[x] = i
简洁还是脚本语言简洁啊。
本文介绍了LeetCode经典题目TwoSum的多种高效解法,包括C++、Java和Python等语言实现,通过使用哈希表将时间复杂度降低至O(n),并探讨了不同容器的选择依据。
804

被折叠的 条评论
为什么被折叠?



