【LeetCode】46. 全排列 Permutations(C++)


题目来源:https://leetcode-cn.com/problems/permutations/

题目描述

  • 给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

题目大意

回溯法

  • 经典dp问题,为了以防排列中出现重复的元素,可以使用bool辅助记录那个元素是否已经在当前排列中,如果对具体递归流程不明白,可以打印排列内容加深理解【注释部分】
  • 注意下图前几行此处的2和3都移除出排列,但1没移除,是因为移除2后,此时i=1,所以还需要走当前递归栈的for循环,也就是下一个元素nums[2]=3入排列中,后续的流程类似
    -在这里插入图片描述
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;
            }
        }
    }
};

复杂度分析

  • 时间复杂度:O(n*n!)。可知回溯的时间复杂度还是很大的,优化的话通常有【剪枝法】,确定了第一个元素后,后续所有元素循环次数依次递减,也就是n!(n的阶乘),需要用O(n)的时间复制到答案数据中,也就是O(n*n!)
  • 空间复杂度:O(n)。因为将所有用到的数据设为全局变量,此处只需要O(n)的递归栈空间就行

猜你喜欢

转载自blog.csdn.net/lr_shadow/article/details/114466003