https://leetcode.com/problems/remove-duplicates-from-sorted-array
중복되는 숫자를 제거하는 문제이다. int[] nums 배열 자체를 수정해야 한다.
nums는 오름차순으로 정렬 돼 있는 상태로 주어진다.
각 원소들의 상대적 위치는 유지 돼야 한다. 이때 nums 배열의 유니크한 원소의 개수(k)를 리턴하면 된다.
예시를 보자. int[] nums = [1, 1, 2] 일 경우 1 이 중복된다. 따라서 nums = [1, 2, _ ]로 변경되고 k는 2가 된다.
int[] nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4] → [0, 1, 2, 3, 4, _, _, _, _, _ ] 이렇게 되고 k는 5가 된다. 기존의 상대적인 순서를 유지한다는 특징이 있다.
구상을 해보자.
- 정렬이 돼 있다는 것은 중복이 존재하는 경우 연속으로 나온다는 뜻이다.
- 배열 자체를 수정하기 때문에 요소를 제거하는 것이 아니라 유효한 요소들을 앞으로 모으는 작업이 필요하다.
- 추가적인 자료구조는 사용할 수 없다. 주어진 int[] nums를 사용해야 한다.
가장 먼저 떠오르는 방법은 중복 요소가 발견되면 가장 뒤로 밀어내는 것이다. 하지만 이 방식은 O(N^2)의 시간복잡도로 매우 비효율적인 알고리즘이 된다.
배열을 순회하면서 교환이 필요하다. 이를 위해 두 개의 포인터를 사용하기로 했다. 즉 투포인터이다.
하나의 포인터는 중복되지 않은 요소의 위치를 가리키고 다른 하나는 배열을 순회하면서 중복을 검사한다.
정렬이 돼 있다 즉 인접한 요소만 보면 중복 검사가 가능하다.
class Solution {
public int removeDuplicates(int[] nums) {
int p1 = 0;
for (int p2 = 1; p2 < nums.length; p2++) {
if (nums[p1] != nums[p2]) {
p1++;
nums[p1] = nums[p2];
}
}
return p1 + 1;
}
}
p1은 유효한 숫자들이 자리 잡을 포인터이다.
p2는 이제 중복이 나오는 지를 확인하고 해당 값의 위치를 이동 시키기 위한 포인터이다.
이 알고리즘은 중복된 숫자가 나오면 마지막 중복 위치를 찾고 지금까지 유효한 위치 다음 위치에 해당 값을 대입하는 동작을 수행한다.
이를 통해 O(N)의 시간복잡도로 문제를 해결할 수 있었다.
'Algorithm > LeetCode' 카테고리의 다른 글
LeetCode 122 - Best Time to Buy and Sell Stock 2 (3) | 2024.09.28 |
---|---|
LeetCode 189 - Rotate Array (0) | 2024.09.28 |
LeetCode 80 - Remove Duplicates from Sorted Array 2 (0) | 2024.09.28 |
LeetCode 27 - Remove Element (1) | 2024.09.27 |
LeetCode 88 - Merge Sorted Array (0) | 2024.09.26 |