2Sum,3Sum,4Sum,…,nSum这类问题
主要用到了hashmap结构,二分法思路,前后指针等
需要将2Sum问题的几种方法,算法时间和空间复杂度深刻理解,并能手写出代码来
https://leetcode.com/problems/two-sum/
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.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
ac代码如下
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
int len = nums.size();
if ( len < 2)
return res;
map<int, int> mp;
for (int i = 0; i < len ; i++){
if (mp[target - nums[i]] != 0){
res.push_back(mp[target - nums[i]] - 1);
res.push_back(i);
}
else{
mp[nums[i]] = i + 1;
}
}
//sort(res.begin(), res.end());
return res;
}
};
class Solution {
public:
int bsearch(vector<int> nums, int left, int right, int key)
{
while (left <= right)
{
int mid = right + (left - right) / 2;
if (nums[mid] == key)
return mid;
else if (nums[mid] < key)
left = mid + 1;
else
right = mid - 1;
}
return -1;
}
vector<int> twoSum(vector<int>& nums, int target) {
int len = nums.size();
vector<int> nums2 = nums;
if (len < 2)
{
vector<int> v;
return v;
}
sort(nums2.begin(), nums2.end());
for (int i = 0; i < len - 1; i++)
{
int findpos = bsearch(nums2, i + 1, len - 1, target - nums2[i]);
if (findpos != -1)
{
int val1 = nums2[i];
int val2 = nums2[findpos];
// 返回结果
vector<int> v;
int vlen = 0;
for (int j = 0; j < len; j++)
{
if (nums[j] == val1 || nums[j] == val2)
{
v.push_back(j);
vlen++;
}
if (vlen == 2)
break;
}
return v;
}
}
vector<int> v;
return v;
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
int len = nums.size();
if (len < 2)
return res;
vector<int> numsTmp = nums;
sort(nums.begin(), nums.end()); //使得有序
//收尾指针法
int sta = 0;
int end = len - 1;
while (sta < end)
{
if (nums[sta] + nums[end] == target)
{
bool f1 = false;
bool f2 = false;
for (int i = 0; i < len; i++)
{
if (f1 && f2)
break;
if (!f1 && numsTmp[i] == nums[sta]) // nums[sta] 可能等于 nums[end]
{
res.push_back(i);
f1 = true;
}
else if (!f2 && numsTmp[i] == nums[end]) // 这里是else if 不是if
{
res.push_back(i);
f2 = true;
}
}
break;
}
else if (nums[sta] + nums[end] < target)
{
sta++;
}
else{
end--;
}
}
return res;
}
};
https://leetcode.com/problems/3sum/
https://leetcode.com/problems/3sum-closest/
https://leetcode.com/problems/4sum/
类似 背包问题
参考
http://www.jianshu.com/p/3d1791cfba53
主要是递归,动态规划等方法
https://leetcode.com/problems/partition-equal-subset-sum/
这题采用dfs查找会超时,采用动态规划来做
参考
http://blog.csdn.net/buptzhengchaojie/article/details/52827357
对比零钱问题(每种数值的钱可以使用多次)
http://blog.csdn.net/qq_26437925/article/details/52101224
class Solution {
public:
bool canPartition(vector<int>& nums) {
int len = nums.size();
int sums = 0;
int maxVal = -1;
for (int i = 0; i < len; i++)
{
sums += nums[i];
if (nums[i] > maxVal){
maxVal = nums[i];
}
}
if (sums % 2 == 1)
return false;
int m = sums / 2;
if (maxVal > m)
return false;
if (maxVal == m)
return true;
vector<bool> dp(m + 1, false); //dp[i] 表示能租构成值为i的子集合
dp[0] = true;
for (int i = 0; i < len; ++i)
{
/*
nums[i] 只会影响 dp[j - nums[i]]到dp[m],
因为这其间的数 dp[] 可以选择使用它,那么看dp[j - nums[i]] 是否是真的
(或不使用用)还是看dp[j]自身
组成m时,每个数字只能使用一次
例如m = 14 ,nums[0] = 7第一次遍历,dp[7] = true,dp[14] = false
j应该从大到小,大的数不会影响前面的数
*/
for (int j = m; j >= nums[i]; --j)
{
dp[j] = dp[j] || dp[j - nums[i]];
}
}
return dp[m];
}
};
class Solution {
public:
bool flag;
//vector ans;
void dfs(int m, int index,vector<int>& nums,int len)
{
if (flag)
return;
if (m < 0)
return;
if (m == 0 && index <= len)
{
flag = true;
/*int alen = ans.size();
for (int i = 0; i < alen; i++){
cout << ans[i] << " ";
}
cout << endl;*/
return;
}
if (index >= len)
return;
//ans.push_back(nums[index]);
dfs(m - nums[index], index + 1,nums,len);
//ans.pop_back();
dfs(m, index + 1,nums,len);
}
bool canPartition(vector<int>& nums) {
int len = nums.size();
int sums = 0;
int maxVal = -1;
for (int i = 0; i < len; i++)
{
sums += nums[i];
if (nums[i] > maxVal){
maxVal = nums[i];
}
}
if (sums % 2 == 1)
return false;
int m = sums / 2;
if (maxVal > m)
return false;
if (maxVal == m)
return true;
flag = false;
dfs(m, 0, nums, len);
return flag;
}
};