🧩 Algorithm
LeetCode : 80. Remove Duplicates from Sorted Array II
iirin
2023. 8. 25. 09:57
문제 먼저 읽기
- 오름차순으로 정수 nums 가 주어진다.
- 각 고유 요소가 최대 두 번만 나타나도록 중복된 요소를 같은 배열안에서 제거합니다. 요소의 상대적 순서는 동일하게 유지해야 합니다.
- java는 배열 길이를 변경할 수 없으므로, 결과를 배열 nums의 index 0부터 배치합니다.
- 중복 제거한 후 요소가 개수를 반환합니다.
Input: nums = [1,1,1,2,2,3]
Output: 5, nums = [1,1,2,2,3,_]
어떻게 풀까?
생각
- 이제 요소가 몇개씩 가능한지 저장해야합니다.
- 순서를 그대로 유지하며 저장되는 개수를 저장해야하므로, 지금 포인터가 요소를 저장할 수 있는 개수를 초기화하며 풀 수 있지 않을까요?
- 별도의 자료구조를 더 정의하는 것은 메모리를 추가로 더 사용하므로 지양하였습니다.
수도코드
class Solution {
public int removeDuplicates(int[] nums) {
int curl = 1;
int stored = 2;
for (int p=1; p<nums.length; p++) {
nums[curl++] = nums[p];
if (nums[p-1] == nums[p]) {
stored --;
}
if (nums[p-1] != nums[p]) {
stored = 2;
}
if (stored == 0) curl --; // 저장가능한 개수가 0이되면 포인터를 뒤로 옮겨서 다음 숫자가 덮어 쓸 수 있도록 한다.
}
return curl;
}
}
결과
Input:
[0,0,1,1,1,1,2,3,3]
Output:
[0,0,1,1,1,2,3,3]
Expected:
[0,0,1,1,2,3,3]
stored
변수 관리에서 실패한 것 같아서 다시 의사 코드를 짜기로했다.
수도코드 2차
class Solution {
public int removeDuplicates(int[] nums) {
int curl = 1; // 두번째 요소부터 입력한다.
int ability = 2;
for (int p=1; p<nums.length; p++) {
nums[curl] = nums[p]; // 먼저 입력한다.
if (nums[curl-1] == nums[p]) { // 이전 입력값과 같으면 저장가능한 숫자를 줄인다.
ability --;
}
if (nums[curl-1] != nums[p]) { // 만약 다르다면 저장 가능한 숫자를 초기화한다.
ability = 2;
}
if (ability > 0) curl ++; // 만약 더 저장할 수 있다면 입력 포인터를 늘려 다음 자리를 채운다.
}
return curl;
}
}
결과 2차
다른 풀이 방식과 문제 회고
class Solution {
public int removeDuplicates(int[] nums) {
if(nums <= 2){
return nums.length;
}
int index = 2;
for(int i = 2; i < nums.length; i++){
if(nums[i] != nums[index - 2]){
nums[index++] = nums[i];
}
}
return index;
}
}
- 이번에는 공간복잡도는 좋은 편이었으나, 시간 복잡도가 다른 사람의 풀이에 대해 많이 떨어졌다.
- nums 길이가 짧을 때 처리와 포인터 방식이 아닌 바로 2개 전 변수와 함께 비교하는 방식으로 코드를 더 단순하게 짤 수 있었다. nums가 이미 정렬되어 있으므로 가능한 방법이었다.