LeetCode之“散列表”:Two Sum && 3Sum && 3Sum Closest && 4Sum
1. Two Sum
题目要求:
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
这道题如果使用Brute Force,在LeetCode上会超时,具体程序如下:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ret;
int sz = nums.size();
for(int i = ; i < sz; i++)
for(int j = i + ; j < sz; j++)
{
if(nums[i] + nums[j] == target)
{
ret.push_back(i);
ret.push_back(j);
return ret;
}
} return ret;
}
如果我们利用哈希表来实现,则时间复杂度能达到O(n),程序如下:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ret;
unordered_map<int, int> hashMap;
int sz = nums.size();
for(int i = ; i < sz; i++)
{
int tmp = target - nums[i];
if(hashMap.find(tmp) != hashMap.end())
{
ret.push_back(hashMap[tmp] + );
ret.push_back(i + );
break;
}
else
hashMap[nums[i]] = i;
} return ret;
}
在上述程序中我们使用了unordered_map这个数据结构,它要比map要快,因为它存贮和访问元素是根据元素的哈希值来进行的。在cplusplus.com上有比较了这两者在访问单个元素时的速度:
unordered_map containers are faster than map containers to access individual elements by their key, although they are generally less efficient for range iteration through a subset of their elements.
2. 3Sum
题目要求:
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- The solution set must not contain duplicate triplets.
For example, given array S = {- - -},
A solution set is:
(-, , )
(-, -, )
该题解法参考自一博文。要解决该题,首先我们将数组排序,然后将其降维(即降为2维),最后再调用Two Sum算法。具体程序中,我们采用的是Two Pointers方法,具体程序如下:
void twoSum(vector<int>& nums, int start, int target, vector<vector<int> >& ret) {
int head = start, tail = nums.size() - ;
while(head < tail)
{
int tmp = nums[head] + nums[tail];
if(tmp < target)
head++;
else if(tmp > target)
tail--;
else
{
ret.push_back({nums[start-], nums[head], nums[tail]}); // 去除重复
int k = head + ;
while(k < tail && nums[k] == nums[head])
k++;
head = k; // 去除重复
k = tail - ;
while(k > head && nums[k] == nums[tail])
k--;
tail = k;
}
}
} vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int> > ret;
sort(nums.begin(), nums.end()); int sz = nums.size();
for(int i = ; i < sz - ; i++)
{
// 去除重复
if(i > && nums[i] == nums[i - ])
continue; int target = - nums[i];
twoSum(nums, i + , target, ret);
} return ret;
}
3. 3Sum Closest
题目要求:
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {- -}, and target = .
The sum that is closest to the target is . (- + + = ).
该题解法跟上题类似:
void threeSumClosest(vector<int>& nums, int start, int target, int& cloSum) {
int head = start, tail = nums.size() - ;
while (head < tail)
{
int tmp = nums[start - ] + nums[head] + nums[tail];
if(tmp > target)
{
if(tmp - target < abs(cloSum - target))
cloSum = tmp;
tail--;
}
else if(tmp < target)
{
if(target - tmp < abs(target - cloSum))
cloSum = tmp;
head++;
}
else
{
cloSum = target;
return;
}
}
} int threeSumClosest(vector<int>& nums, int target) {
int cloSum = INT_MAX - ; // 减去10000,以防溢出
sort(nums.begin(), nums.end()); // 要充分利用已排序这个条件
int sz = nums.size();
for(int i = ; i < sz - ; i++)
{
// 去除重复
if(i > && nums[i] == nums[i-])
continue; threeSumClosest(nums, i + , target , cloSum);
} return cloSum;
}
4. 4Sum
题目要求:
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
- Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
- The solution set must not contain duplicate quadruplets.
For example, given array S = { - - }, and target = .
A solution set is:
(-, , , )
(-, -, , )
(-, , , )
该题解法跟3Sum类似:
void twoSum(vector<int>& nums, int start, int target, int first, int second, vector<vector<int>>& ret)
{
int head = start, tail = nums.size() - ;
while(head < tail)
{
int tmp = nums[head] + nums[tail];
if(tmp < target)
head++;
else if(tmp > target)
tail--;
else
{
ret.push_back({first, second, nums[head], nums[tail]}); // 去除重复
int k = head + ;
while(k < tail && nums[k] == nums[head])
k++;
head = k; // 去除重复
k = tail - ;
while(k > head && nums[k] == nums[tail])
k--;
tail = k;
}
}
} vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ret;
sort(nums.begin(), nums.end());
int sz = nums.size();
for(int i = ; i < sz - ; i++)
{
// 去除重复
if(i > && nums[i] == nums[i-])
continue;
for(int j = i + ; j < sz - ; j++)
{
// 去除重复
if(j > i + && nums[j] == nums[j-])
continue;
twoSum(nums, j + , target - nums[i] - nums[j], nums[i], nums[j], ret);
}
} return ret;
}
LeetCode之“散列表”:Two Sum && 3Sum && 3Sum Closest && 4Sum的更多相关文章
- LeetCode之“散列表”:Isomorphic Strings
题目链接 题目要求: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic i ...
- LeetCode之“散列表”:Contains Duplicate && Contains Duplicate II
1. Contains Duplicate 题目链接 题目要求: Given an array of integers, find if the array contains any duplica ...
- LeetCode之“散列表”:Single Number
题目链接 题目要求: Given an array of integers, every element appears twice except for one. Find that single ...
- LeetCode之“散列表”:Valid Sudoku
题目链接 题目要求: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku boar ...
- LeetCode解题报告—— Container With Most Water & 3Sum Closest & Letter Combinations of a Phone Number
1. Container With Most Water Given n non-negative integers a1, a2, ..., an, where each represents a ...
- LeetCode:3Sum, 3Sum Closest, 4Sum
3Sum Closest Given an array S of n integers, find three integers in S such that the sum is closest t ...
- LeetCode 339. Nested List Weight Sum (嵌套列表重和)$
Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...
- Leetcode 两数之和 (散列表)
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...
- [leetcode]364. Nested List Weight Sum II嵌套列表加权和II
Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...
随机推荐
- 多线程(三) 实现线程范围内模块之间共享数据及线程间数据独立(ThreadLocal)
ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.JDK 1.2的版本中就提供java.lang.ThreadLocal,使用这个工具类可以很简洁地编写出优美的多线程程序,Threa ...
- 使用DWR实现自动补全 类似百度搜索框的自动显示效果
使用DWR实现自动补全 自动补全:是指用户在文本框中输入前几个字母或汉字的时候,自动在存放数据的文件或数据库中将所有以这些字母或汉字开头的数据提示给用户供用户选择 在日常上网过程中,我们经常使用搜索引 ...
- win32贪吃蛇实现
写程序是一个循序渐进的过程,一开始都是加加减减,修修补补,这和我们做企业做创新的原理都是一样的,没有一蹴而就的成功,最近看了周鸿祎的<我的互联网方法论>蛮有启发,分享给大家几句摘抄: 1. ...
- Java遍历时删除List、Set、Map中的元素(源码分析)
在对List.Set.Map执行遍历删除或添加等改变集合个数的操作时,不能使用普通的while.for循环或增强for.会抛出ConcurrentModificationException异常或者没有 ...
- Android摄像头照相机技术-android学习之旅(八)
简介 Android SDK支持Android设备内置的照相机.从Android2.3开始支持多个摄像头(主要指前置摄像头和后置摄像头).通过照片相可以拍照和录像. 需要考虑的问题 是否支持照相机 快 ...
- windows与linux的文件夹共享
公司配备了一台性能还算不错的电脑,不过是台式机.我在上面装了ubuntu,但是我的代码工作目录全部都在我自己的win7笔记本上.有时程序开多了就容易卡,于是想到用装ubuntu的台式机来访问我win7 ...
- RecyclerView嵌套RecyclerView
ListView嵌套GridView http://blog.csdn.net/baiyuliang2013/article/details/42646289 RecyclerView下拉刷新上拉加载 ...
- shell脚本实现冒泡排序
手动输入一行字符串,并对其排序. 脚本如下: #!/bin/bash #a test about sort echo "please input a number list" re ...
- UNIX网络编程——经常使用的套接字选项
1.设置/获取套接字选项 int setsockopt(int socket, int level, int option_name, const void *option_value, sockle ...
- 如何设制 select 不可编辑 只读
1. <select style="width:195px" name="role" id="role" onfocus=" ...