table of Contents
Source of the subject: https://leetcode-cn.com/problems/permutations/
Title description
- Given a sequence without repeated numbers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1 ,2],
[3,2,1]
]
General idea
- It can be regarded as a classic backtracking problem, returning all possible full permutations. For full permutation problems, you can use the backtracking method to solve ( in the case of a small amount of data, because the time complexity of the backtracking method is generally high ), you can refer to the ideas [The following more detailed problem solutions]
https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
Backtracking
- The classic dp problem, in order to prevent duplicate elements in the arrangement, you can use bool to assist in recording whether the element is already in the current arrangement. If you don’t understand the specific recursive process, you can print the arrangement content to deepen your understanding [Notes]
- Note that the 2 and 3 in the first few lines of the figure below are removed from the arrangement, but 1 is not removed, because after removing 2, i=1, so you need to go through the for loop of the current recursive stack, which is the next element nums [2] = 3 into the arrangement , the subsequent processes similar
-
class Solution {
public:
vector<vector<int>> ret;
vector<int> ans;
vector<bool> used;
int n;
vector<vector<int>> permute(vector<int>& nums) {
n = nums.size();
used.assign(n, false);
dfs(nums, 0);
return ret;
}
void dfs(vector<int>&nums, int depth){
if(depth == n){
ret.push_back(ans);
return;
}
for(int j = 0; j < n ; ++j){
if(!used[j]){
ans.push_back(nums[j]);
used[j] = true;
//cout << "递归之前=> " << "\t" << depth << "\t";
//for (auto num : ans) {
// cout << num << ",";
//}
dfs(nums, depth + 1);
used[j] = false;
ans.pop_back();
//cout << "递归之后=> " << "\t" << depth << "\t";
//for (auto num : ans) {
// cout << num << ",";
//}
//cout << endl;
}
}
}
};
Complexity analysis
- Time complexity: O(n*n!). It can be seen that the time complexity of backtracking is still very large. For optimization, there is usually a [pruning method]. After the first element is determined, the number of cycles of all subsequent elements decreases sequentially, that is, n! (the factorial of n), which requires O (n) time is copied into the answer data, which is O(n*n!)
- Space complexity: O(n). Because all the data used is set as global variables, only O(n) recursive stack space is needed here.