/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {number} n
* @return {void} Do not return anything, modify nums1 in-place instead.
*/
var merge = function(nums1, m, nums2, n) {
if(nums2.length === 0){
// 반환값 필요 없음. input으로 들어온 nums1 자체로 정답.
return;
}
// 큰 흐름
// 1. nums2의 값을 nums1으로 옮긴다.
// 2. nums1을 정렬한다.
// 1번 플로우(nums1 자체를 변경해야하므로 splice 활용)
// 1. nums1의 m 인덱스부터 원소를 지우고 nums2 배열의 값을 넣는다.
for(let i = 0; i < n; i++){
nums1.splice(m + i, 1, nums2[i]);
}
// 2번 플로우
nums1.sort((a, b) => {
return a - b;
});
};
이 문제는 nums1을 변경한다는 것이 주요 포인트이다.
아무래도 공간 복잡도를 최소화해서 두 배열을 합치는 방법을 생각해 내라는 것이 목적인 듯 하다.
받아온 값을 변경하고자 한다면 splice()를 떠올릴 수 있겠다.
또한, nums1 배열은 m+n의 길이를 가지며 m번 인덱스부터 0의 값을 가진다.
즉, nums1과 nums2를 병합하기 위해서 nums1의 m번 인덱스부터 nums2의 값으로 교체해주면 되는 것이다.
마지막으로, 오름차순 정렬을 위해 sort()를 해주면 된다.
여기서 주의할 점은, nums1 배열은 정수로 이루어져있다는 것이다.
즉, 음수가 존재한다.
따라서, sort()만 사용하는 것이 아니라, 오름차순 로직을 추가하는 것으로 음수까지 정렬할 수 있도록 해준다.
var merge = function(nums1, m, nums2, n) {
for (let i = m, j = 0; j < n; i++, j++) {
nums1[i] = nums2[j];
}
nums1.sort((a, b) => a - b);
};
아주 간단하게 해결하신 분이 계셨다.
배열의 값을 바꾸는 것이 주 목적이기 때문에, 배열 원소를 재할당하는 것으로 이를 해결하셨다.
배열의 기본 특징을 이용한 방법이 되겠다.
문제의 제목인 Merge Sorted Array, 즉, 오름차순 정렬된 두 배열을 병합 할 때 쓰이는 기초 알고리즘인
two pointer algorithm을 사용하셨다.
var merge = function(nums1, m, nums2, n) {
let i = m - 1;
let j = n - 1;
let k = m + n - 1;
while (j >= 0) {
if (i >= 0 && nums1[i] > nums2[j]) {
nums1[k--] = nums1[i--];
} else {
nums1[k--] = nums2[j--];
}
}
};
nums1, nums2 배열의 끝에서부터 앞쪽으로 순회하면서
대소 비교를 통해 nums1의 0값이 들어있는 부분에 더 큰 값을 넣는다.
참고로, 현재 nums1은 m+n의 길이를 가지며, m번 인덱스부터는 0의 값을 가진다.
만약 nums2의 값이 더 크다면 j 포인터를 감소시켜서 nums2의 포인터를 진행시킨다.
nums1, nums2는 이미 오름차순 정렬이 되어있으므로, 두 배열의 대소 비교를 통해 배열을 만들어 나가면 자연스럽게 오름차순 정렬된 병합 배열이 생성된다.
코테 준비 파이팅입니다 :)