Estaba trabajando en esta pregunta de leetcode: https://leetcode.com/problems/subsets/
y se me ocurrió esta solución:
INPUT = [1, 2, 3]
var subsets = function(nums) { let ans = [] for (let num of nums) { // DUPLICATE ARRAY ans = [...ans, ...ans] const size = ans.length // ITERATE THROUGH LAST HALF OF ARR for (let i = size / 2; i < size; i++) { ans[i].push(num) <------------- THIS AINT RIGHT :( } ans.push([num]) } return [[], ...ans] }; ANS = [[],[1,2,3,3],[1,2,3,3],[2,3],[1,2,3,3],[1,2,3,3],[2,3],[3]] (INCORRECT)Sin embargo, parecía estar empujando valores incorrectamente en múltiples índices por alguna razón. Después de jugar con el código pensando que mi lógica es correcta, se me ocurrió esto:
var subsets = function(nums) { let ans = [] for (let num of nums) { // DUPLICATE ARRAY ans = [...ans, ...ans] const size = ans.length for (let i = size / 2; i < size; i++) { ans[i] = [...ans[i], num] <--------------- THIS WORKS } ans.push([num]) } return [[], ...ans] }; ANS = [[],[1],[1,2],[2],[1,3],[1,2,3],[2,3],[3]] (correct) Y eso terminó funcionando... ¿Por qué sucede esto? No arr[i].push(num) es más o menos lo mismo que arr[i] = [...arr[i], num]
La razón es que los subarreglos no se copian cuando lo hace:
ans = [...ans, ...ans] Esto simplemente produce las mismas referencias de subarreglo. Esto significa que cuando push uno de los subarreglos en la segunda mitad de ans , verá el efecto también a través de la primera mitad de ans , ya que ambas mitades hacen referencia a los mismos subarreglos.
Entonces, para resolver esto, haga una copia más profunda al producir la segunda mitad:
ans = [...ans, ...ans.map(arr => Array.from(arr))]La segunda versión funcional realiza esta copia más profunda en la línea que marcó.