[브러쉬 질문] 정렬된 배열에서 중복 삭제

시리즈 기사 디렉토리

정렬된 배열에서 중복 제거


여기에 이미지 설명 삽입

머리말

데이터 구조는 프로그래밍 세계에서 매우 중요하며 특히 큰 공장에서의 인터뷰는 필수 항목입니다.

1. 주제

배열 번호가 오름차순으로 주어지면 각 요소가 한 번만 나타나도록 제자리에서 반복되는 요소를 삭제하고 삭제된 배열의 새 길이를 반환하십시오. 요소의 상대적 순서는 일관되어야 합니다. 그런 다음 고유한 요소의 수를 숫자로 반환합니다.

nums의 고유한 요소 수가 k인 것을 고려하면 솔루션이 통과할 수 있도록 다음을 수행해야 합니다.

  • nums의 첫 번째 k 요소가 원래 nums에 나타난 순서대로 고유한 요소를 포함하도록 배열 nums를 변경합니다. nums의 나머지 요소는 nums의 크기에 중요하지 않습니다.
  • k를 반환합니다.

출처: leetcode
링크: https://leetcode.cn/problems/remove-duplicates-from-sorted-array/
제목: 26. 정렬된 배열에서 중복 제거

1.2 판정기준

시스템은 다음 코드를 사용하여 솔루션을 테스트합니다.

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    
    
    assert nums[i] == expectedNums[i];
}

모든 어설션이 통과하면 솔루션이 통과됩니다.

1.3 예시

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

2. 문제 해결

2.1 이중 포인터 순방향 조회

시간복잡도는 O(n)이며 내부 검색은 추가 공간을 소비하지 않습니다.
여기에 이미지 설명 삽입

2.2 솔루션

하나의 포인터 i는 배열 순회에 사용되고 다른 포인터 j는 유효한 배열의 마지막 위치를 가리킵니다.
i가 가리키는 값이 j와 일치하지 않는 경우(반복되지 않음)에만 i의 값이 j의 다음 위치에 추가됩니다.

class Solution {
    
    
    public int removeDuplicates(int[] nums) {
    
    
        int n = nums.length;
        int j = 0;
        for (int i = 0; i < n; i++) {
    
    
            if (nums[i] != nums[j]) {
    
    
                nums[++j] = nums[i];
            }
        }
        return j + 1;
    }
}
  • 시간 복잡도: O(n)
  • 공간 복잡도: O(1)

2.2, 역순으로 삭제

Java에서 ArrayList 컬렉션의 데이터를 완전히 삭제할 수 없는 이유는 이 질문에서 파생될 수 있습니다.
역삭제를 통해 컬렉션의 인덱스/값이 변경되지 않도록 보장할 수 있으며, 시간 복잡도도 O(n)입니다
(역삭제 시 다른 데이터의 일련번호 변경에는 영향을 미치지 않음).
여기에 이미지 설명 삽입

3. 요약

이 글은 이중 포인터 순방향 검색과 역순 삭제 알고리즘을 통해 배열에서 중복을 삭제하고 고유한 숫자의 길이를 반환합니다.이 두 알고리즘 모두 추가 공간을 차지하지 않습니다.

추천

출처blog.csdn.net/s445320/article/details/131375070