一、2Sum,3Sum,4Sum,…,nSum这类问题
主要用到了hashmap结构,前后指针的方法
1、采用map结构,时间复杂度O(n)
#include <iostream>
#include <vector>
#include <map>
using namespace std;
class Solution
{
public:
//hash映射
void twoSum(vector<int> num, int sum)
{
int len = num.size();
if (len < 2 || sum < 0)
return;
map<int, int> map;
for (int i = 0; i < len; ++i)
map[num[i]] = i;
for (int i = 0; i < len; ++i)
{
int temp = sum - num[i];
if (map.count(temp) && map[temp] != i)
{
cout << i << " " << map[temp] << endl;
break;
}
}
}
};
int main()
{
Solution s;
vector<int> num{ 1,2,3, 7 };
s.twoSum(num, 9);
system("pause");
return 0;
}
2、前后指针
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution
{
public:
void twoSum(vector<int> num, int sum)
{
int len = num.size();
if (len < 2 || sum < 0)
return;
//sort(num.begin(), num.end());
int begin = 0, end = len - 1;
while (begin < end)
{
if (num[begin] + num[end] == sum)
{
cout << begin << " " << end << endl;
break;
}
if (num[begin] + num[end] < sum)
begin++;
else
end--;
}
}
};
int main()
{
Solution s;
vector<int> num{ 1, 2, 4, 7};
s.twoSum(num, 9);
system("pause");
return 0;
}
二、找到和为定值的多个数
类似 背包问题
注意到取n,和不取n个区别即可,考虑是否取第n个数的策略,可以转化为一个只和前n-1个数相关的问题。
- 如果取第n个数,那么问题就转化为“取前n-1个数使得它们的和为sum-n”,对应的代码语句就是sumOfkNumber(sum - n, n - 1);
- 如果不取第n个数,那么问题就转化为“取前n-1个数使得他们的和为sum”,对应的代码语句为sumOfkNumber(sum, n - 1)。
参考代码如下:
list<int>list1;
void SumOfkNumber(int sum, int n)
{
// 递归出口
if (n <= 0 || sum <= 0)
return;
// 输出找到的结果
if (sum == n)
{
// 反转list
list1.reverse();
for (list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)
cout << *iter << " + ";
cout << n << endl;
list1.reverse()//此处还需反转回来
}
list1.push_front(n); //典型的01背包问题
SumOfkNumber(sum - n, n - 1); //“放”n,前n-1个数“填满”sum-n
list1.pop_front();
SumOfkNumber(sum, n - 1); //不“放”n,n-1个数“填满”sum
}