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. ...
随机推荐
- ROS探索总结(十八)——重读tf
在之前的博客中,有讲解tf的相关内容,本篇博客重新整理了tf的介绍和学习内容,对tf的认识会更加系统. 1 tf简介 1.1 什么是tf tf是一个让用户随时间跟踪多个参考系的功能包,它使用一种树型数 ...
- 查看4k对齐,激活.net framework 3.5
查看是否4k对齐 Win+R,打开运行窗口,在窗口中输入“msinfo32",组件”--“存储”--“磁盘”.然后可以在右边栏看到“分区起始偏移”,我们图例中有2个数值,分别是:32256字 ...
- Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)
csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...
- IE下的deflate模式
浏览器有一个非常有用的特性:自动解压. 在使用AJAX请求数据的时候,数据在服务器端压缩传输,在浏览器端自动解压,请求直接得到解压后的结果. 在Request Header中,一般会列出浏览器支持的压 ...
- TCP连接建立系列 — 客户端的端口选取和重用
主要内容:connect()时的端口选取和端口重用. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 端口选取 connect()时本地端口是如何选取的呢 ...
- 【移动开发】一张图搞定Activity和Fragment的生命周期
- iterm2 快捷键
最近开始使用mac,用iterm2的终端,有些快捷键纪录下. 标签 新建标签:command + t 关闭标签:command + w 切换标签:command + 数字 或者 command + 左 ...
- 当图片验证码遇上JSP
今天看到了一个关于使用JSP方式生成图片验证码 的小例子,感觉真的是很不错,拿来分享一下. 原理 对于图片验证码,我们在审查元素的时候会方便的看出是<img src="#" ...
- 11 OptionsMenu 菜单
OptionsMenu 选项菜单(系统菜单 ) OptionsMenu:系统级别菜单 菜单的使用步骤: 1. res里的menu里添加布局 在布局里写菜单项 2. 在逻辑代码中使用OnCreateOp ...
- (一〇一)集成静态库RHAddressBook实现OC访问通讯录
使用官方的AddressBook框架仅能使用C语言访问通讯录,十分不便,这里介绍集成第三方框架RHAddressBook的方法,该框架可以通过OC访问和操作通讯录. 该框架是一个静态库,集成比较复杂. ...