Un método (Método de cambio):
público de clase L46 { público vacío retroceso ( int n, ArrayList <Integer> nums, List <Lista <entero >> salida, int primero) { si (primera == n) { output.add ( nuevo ArrayList <Integer> (nums) ); } Para ( int i = primero; i <n; i ++ ) { Collections.swap (nums, primero, i); backtrack (n, nums, de salida, primero 1 ); Collections.swap (nums, primero, i); } } Pública Lista <Lista <entero >> permute ( int[] Nums) { Lista <Lista <entero >> salida = nueva LinkedList <> (); ArrayList <Integer> nums_lst = nuevo ArrayList <> (); para ( int num: nums) { nums_lst.add (NUM); } Int n = nums.length; backtrack (n, nums_lst, de salida, 0 ); volver de salida; } }
El segundo (lento):
clase de soluciones { pública Lista <Lista <entero >> permute ( int [] nums) { int n = nums.length; Lista <Lista <entero >> salida = nuevo ArrayList <> (factorial (n)); si (n == 0) de retorno de salida; boolean [] utilizado = nuevo boolean [n]; Lista <entero> path = nuevo ArrayList <> (); dfs (nums, n, 0 , trayectoria, se utiliza, de salida); volver de salida; } Privada int factorial (int n) { int res = 1 ; para ( int i = 2; i <= n; i ++ ) { res * = i; } Devolver res; } Privados vacíos DFS ( int [] nums, int len, int profundidad, List <Integer> ruta, boolean [] utilizado, List <Lista <entero >> res) { si (profundidad == len) { res.add (ruta ); volver ; } Para ( int i = 0; i <len; i ++ ) { SI (! Se utiliza [I]) { // 1, todos los intentos de crear una nueva variable que representa el "estado" actual. List <Integer> = newpath nueva nueva ArrayList <> (ruta); newPath.add (los nums [I]) ; Boolean [] = newUsed nuevo nuevo Boolean [len]; System.arraycopy (Se utiliza, 0, newUsed, 0 , LEN); newUsed [I] = true ; DFS (la nums, len, profundidad . + 1 , newpath, newUsed, RES) ; // 2, sin backtracking } } } }
El tercero (el más rápido): método A de backtracking
público de clase L46_2 { Lista <Lista <entero >> ans = nuevo ArrayList <> (); boolean [] visitada; pública Lista <Lista <entero >> permute ( int [] nums) { visitado = nueva booleano [nums.length]; helper (nums, nueva ListaEnlazada <> ()); volver ans; } Void helper ( int [] nums, LinkedList <Integer> lista) { si (list.size () == nums.length) { ans.add ( new ArrayList <> (lista));
Después // objeto variable de ruta señaló a una sola, en un recorrido en profundidad recursiva del proceso completo, porque la raíz volvió
// (como hemos dicho antes, de vuelta de los nodos de unión superficial profunda, la necesidad desactivada antes), por lo que la parte posterior ruta a la raíz de esta variable está vacía después de todo.
// dirección en Java, ya que se pasan por valor, tipo de variable objeto durante el paso de parámetros, una copia de todas las variables.
// La dirección se agrega a la variable de res, pero en puntos de datos a la misma dirección de memoria, así que veremos seis lista vacía de objetos.
volver ; } Para ( int i = 0; i <nums.length; i ++ ) { si (! Visitado [i]) { visitado [i] = verdadero ; list.add (nums [i]); helper (nums, lista); list.removeLast (); visitado [i] = false ; } } } }