给定一个没有重复数字的序列,返回其所有可能的全排列。【46】
#include<stdio.h>
#include<iostream>
#include<vector>
using namespace std;
/* 保存所有组合的结果 */
std::vector<vector<int>> m_output;
void backtrack(int n, std::vector<int>& curr, int first)
{
if(first == n)
m_output.push_back(curr);
for (int i = first; i < n; i++)
{
std::swap(curr[i], curr[first]);
backtrack(n, curr, first + 1);
std::swap(curr[i], curr[first]);
}
}
void arrage(int n)
{
std::vector<int> m_curr;
for (int i = 1; i < n + 1; i++)
m_curr.push_back(i);
backtrack(n, m_curr, 0);
}
int main(int argc, char *argv[])
{
arrage(4);
/* 打印输出结果 */
for (int i = 0; i < m_output.size(); i++)
{
for (int j = 0; j < m_output[i].size(); j++)
{
cout << m_output[i][j] << " ";
}
cout << endl;
}
system("pause");
return 0;
}
给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。
返回可以使最终数组和为目标数 S 的所有添加符号的方法数。【494】
方法一:枚举解法
void caculate(vector<int>& nums, int i, int sum, int S, int &_count)
{
if(i == nums.size() - 1)
{
if(sum == S)
_count++;
}
else
{
caculate(nums, i + 1, sum + nums[i + 1], S, _count);
caculate(nums, i + 1, sum - nums[i + 1], S, _count);
}
}
int findTargetSumWays(vector<int>& nums, int S)
{
int _count = 0;
caculate(nums, -1, 0, S, _count);
return _count;
}
复杂度:
-
时间复杂度:O(2^N),其中 N 是数组
nums
的长度。 -
空间复杂度:O(N)O(N),为递归使用的栈空间大小。
方法二:动态规划解法
#define LENGTH 2001
int findTargetSumWays(vector<int>& nums, int S)
{
int _count = 0;
/* 采用动态规划的基本思想(背包问题) */
/* dp[i][j] = dp[i - 1][j - nums[i]] + dp[i - 1][j + nums[i]] */
/* dp[0][j if j == + or - nums[0]] = dp[0][] */
/* dp[nums.size() - 1][S] */
/* 另外一点就是考虑将此状态方程写为迭代式 */
/* */
int _dp[20][2001] = { 0 };
/* 具体实现状态方程 */
for (int i = 0; i < nums.size(); i++)
{
int next_sum1 = 0;
int next_sum2 = 0;
for (int j = -1000; j < 1001; j++)
{
/* 排除和过滤操作 */
if (i == 0) {
if (j == nums[0] || -j == nums[0])
_dp[0][j + 1000] += 1;
else
_dp[0][j + 1000] = 0;
continue;
}
if (j - nums[i] + 1000 < 0)
next_sum1 = 0;
else
next_sum1 = _dp[i - 1][j - nums[i] + 1000];
if (j + nums[i] + 1000 < 0)
next_sum2 = 0;
else
next_sum2 = _dp[i - 1][j + nums[i] + 1000];
_dp[i][j + 1000] = next_sum1 + next_sum2;
}
}
_count = _dp[nums.size() - 1][S + 1000];
return _count;
}
复杂度:
- 时间复杂度,O(N * sum)
- 空间复杂度,O(N * sum)