#javascript #algorithm
Вопрос:
Работал над этим вопросом с литкодом: https://leetcode.com/problems/subsets/
и придумал это решение:
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)
Однако по какой-то причине он, похоже, неправильно вставлял значения в несколько индексов. После возни с кодом, думая, что моя логика верна, я пришел к следующему:
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)
И это в конечном итоге сработало… Почему это происходит? arr[i].push(num)
В значительной степени это не то же самое, что arr[i] = [...arr[i], num]
Комментарии:
1. Я временно удалил свой ответ, потому что нам нужно знать ваши данные (пожалуйста, включите их в сам вопрос). И я сосредоточился на вопросе о том, почему
push
это не эквивалентно, а не для того, чтобы ответить на реальный вызов 🙂2. Это не работает. Вот почему я так растерян.
ans = [[0], [1], [2]]
. Так что это было бы дублированиемans = [[0], [1], [2], [0], [1], [2]]
. Поэтому, повторяя вторую половину, push должен правильно нажимать… но это не так…3. Входные данные [1, 2, 3]
4. Входные данные таковы
nums = [0, 1, 2]
. Желаемый результат таков[[],[1],[1,2],[2],[1,3],[1,2,3],[2,3],[3]]
. Вы можете видеть, что после каждого цикла я нажимаю[num]
наans
arr5. Да, теперь я понимаю, что ты делаешь, @sssyn.
Ответ №1:
Причина в том, что подмассивы не копируются, когда вы это делаете:
ans = [...ans, ...ans]
Это просто создает одни и те же ссылки на подмассивы. Это означает , что когда вы push
перейдете к одному из подмножеств во второй половине ans
, вы увидите эффект также и в первой половине ans
, поскольку обе половины ссылаются на одни и те же подмножества.
Поэтому, чтобы решить эту проблему, сделайте более глубокую копию при создании второй половины:
ans = [...ans, ...ans.map(arr => Array.from(arr))]
Вторая, рабочая версия, выполняет эту более глубокую копию в строке, которую вы отметили.
Комментарии:
1. Ааааа, в этом есть смысл. Чертовы ссылки на массивы… Спасибо @trincot!