Web Development/algorithm
[Algorithm][LeetCode 1920] buildArray
devflate
2025. 5. 6. 11:50
배열 인덱스를 활용한 간단한 배열 구성 문제 - buildArray
LeetCode의 배열 문제 중 하나인 “Build Array from Permutation” 문제를 정리해보았습니다.
문제 설명
0부터 시작하는 순열 배열 nums
가 주어졌을 때, ans[i] = nums[nums[i]]
가 되도록 배열 ans
를 구성하여 반환하는 문제입니다.
여기서 0 기반 순열(zero-based permutation)은 0
부터 nums.length - 1
까지의 정수를 중복 없이 포함한 배열을 의미합니다.
예제 1
Input: nums = [0,2,1,5,3,4]
Output: [0,1,2,4,5,3]
설명:
ans = [
nums[nums[0]], // nums[0] = 0 → nums[0] = 0
nums[nums[1]], // nums[1] = 2 → nums[2] = 1
nums[nums[2]], // nums[2] = 1 → nums[1] = 2
nums[nums[3]], // nums[3] = 5 → nums[5] = 4
nums[nums[4]], // nums[4] = 3 → nums[3] = 5
nums[nums[5]] // nums[5] = 4 → nums[4] = 3
]
예제 2
Input: nums = [5,0,1,2,3,4]
Output: [4,5,0,1,2,3]
풀이 1 - 보조 배열 사용 (시간복잡도 O(N), 공간복잡도 O(N))
배열의 인덱스를 사용하면 O(1) 시간에 요소에 접근할 수 있기 때문에 반복문을 통해 ans[i] = nums[nums[i]]
를 그대로 구현할 수 있습니다.
/**
* @param {number[]} nums
* @return {number[]}
*/
var buildArray = function(nums) {
const ans = [];
for (let i = 0; i < nums.length; i++) {
ans.push(nums[nums[i]]);
}
return ans;
};
풀이 2 - in-place 방식 (시간복잡도 O(N), 공간복잡도 O(1))
배열의 공간 복잡도를 줄이기 위해 기존 nums
배열 자체를 최종 결과 배열로 변형하는 방법입니다. 단, 이 방식은 기존 배열을 변경해도 되는 경우에만 사용할 수 있습니다.
핵심 아이디어는 기존 값(nums[i]
)과 미래 값(nums[nums[i]]
)을 하나의 숫자에 동시에 저장하는 것입니다.
왜 인코딩이 필요한가?
단순히 nums[i] = nums[nums[i]]
로 할 경우, 기존의 nums[i]
값이 손실되어 이후에 필요한 nums[nums[i]]
계산이 틀어지게 됩니다. 이를 해결하기 위해 한 숫자에 두 값을 인코딩합니다:
nums[i] = nums[i] + n * (nums[nums[i]] % n)
- n
은 배열의 길이이며,
- nums[nums[i]] % n
을 통해 원래의 값을 추출할 수 있습니다.
- 이렇게 하면 기존 값은 nums[i] % n
, 미래 값은 Math.floor(nums[i] / n)
으로 각각 분리할 수 있습니다.
전체 코드
/**
* @param {number[]} nums
* @return {number[]}
*/
var buildArray = function(nums) {
const n = nums.length;
// 1단계: 미래 값을 인코딩하여 현재 값에 덧붙임
for (let i = 0; i < n; i++) {
nums[i] = nums[i] + n * (nums[nums[i]] % n);
}
// 2단계: 미래 값만 추출하여 덮어쓰기
for (let i = 0; i < n; i++) {
nums[i] = Math.floor(nums[i] / n);
}
return nums;
};
정리
- 보조 배열을 사용하면 구현은 간단하지만 추가 메모리를 사용하게 됩니다.
- in-place 방식은 메모리 사용을 줄일 수 있지만, 수학적 인코딩/디코딩 기법이 필요합니다.
- 이 문제처럼 값의 범위가 제한되어 있을 때(in 0 ~ n-1), 두 값을 한 숫자에 넣는 방식이 특히 유용합니다.