Leetcode 46. Array completo (método clásico de retroceso)

Jueves 18 de marzo de 2021, hace buen tiempo [No lamentes el pasado, no desperdicies el presente, no temas el futuro]


1. Introducción

46. ​​Arreglo completo
Inserte la descripción de la imagen aquí

2. Solución de problemas (retrospectiva de Dafa)

2.1 Método de matriz temporal

class Solution {
    
    
public:
    unordered_set<int> uset; // 利用哈希表判断元素是否遍历过了
    vector<vector<int>> res;
    vector<vector<int>> permute(vector<int>& nums) {
    
    
        vector<int> tmp; // 临时数组,存放每一个排列的结果
        dfs(nums,tmp,0);
        return res;
    }

    void dfs(vector<int>& nums, vector<int>& tmp, int n){
    
    
        // 终止条件,所有位都遍历完了
        if(n==nums.size()){
    
    
            res.push_back(tmp);
            return;
        }
        for(int num:nums){
    
    
            // 如果 num 还没有遍历
            if(uset.find(num)==uset.end()){
    
    
                // 加入哈希表和临时数组
                uset.insert(num);
                tmp.push_back(num);

                // 继续遍历下一位
                dfs(nums,tmp,n+1);

                // 遍历完之后记得还原,避免分支污染
                uset.erase(num);
                tmp.pop_back();
            }
        }
    }
};

Esta es la respuesta que escribí cuando lo hice por primera vez y es más fácil de entender. Aunque se puede aprobar, requiere más tiempo que el método oficial (el método de intercambio a continuación).

2.2 Método de intercambio

class Solution {
    
    
public:
    void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len){
    
    
        // 所有数都填完了
        if (first == len) {
    
    
            res.emplace_back(output);
            return;
        }
        for (int i = first; i < len; ++i) {
    
    
            // 动态维护数组
            swap(output[i], output[first]);
            // 继续递归填下一个数
            backtrack(res, output, first + 1, len);
            // 撤销操作
            swap(output[i], output[first]);
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
    
    
        vector<vector<int> > res;
        backtrack(res, nums, 0, (int)nums.size());
        return res;
    }
};

El método de intercambio también es un método estándar para resolver el problema de la disposición completa Aunque el código es simple, requiere un poco de esfuerzo entenderlo.

La siguiente imagen ayuda a comprender:
Inserte la descripción de la imagen aquí

* Análisis de complejidad

Inserte la descripción de la imagen aquí
El cálculo de la complejidad del tiempo es más difícil de entender. Puede consultar la siguiente imagen para comprender:
Inserte la descripción de la imagen aquí
sume el número de intercambios de cada capa, puede obtener el número total de llamadas:
Inserte la descripción de la imagen aquí
Entonces puede derivar la fórmula anterior.


referencias

https://leetcode-cn.com/problems/permutations/solution/quan-pai-lie-by-leetcode-solution-2/

https://blog.csdn.net/u013905744/article/details/113779407

Supongo que te gusta

Origin blog.csdn.net/m0_37433111/article/details/114968607
Recomendado
Clasificación