LeetCode 데이터 구조와 알고리즘 II의 두 배열의 교차점

함께 쓰는 습관을 들이세요! "너겟 데일리 뉴플랜 · 4월 업데이트 챌린지" 참여 12일차 입니다. 클릭하시면 이벤트 내용을 보실 수 있습니다 .

주제

350. 두 배열의 교차 II

두 정수 배열  의 nums1합 이 주어지면 nums2두 배열의 교집합을 배열로 반환하십시오. 반환된 결과에서 각 요소의 발생 횟수는 해당 요소가 두 배열에 모두 나타나는 횟수와 같아야 합니다(발생 횟수가 일치하지 않으면 더 작은 값으로 간주됨). 출력 결과의 순서는 무시할 수 있습니다.

예 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
复制代码

예 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
复制代码

힌트:

1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
复制代码

고급: 주어진 배열이 이미 정렬되어 있으면 어떻게 됩니까? 알고리즘을 어떻게 최적화하시겠습니까?
nums1의 크기가 nums2보다 작은 경우 어떤 방법이 더 낫습니까?
nums2의 요소가 디스크에 저장되어 있고 메모리가 제한되어 있으며 모든 요소를 ​​한 번에 메모리에 로드할 수 없는 경우 어떻게 해야 합니까?

답변

문제 해결 분석

문제 해결 아이디어

  1. 아이디어: 두 배열을 정렬한 다음 이중 포인터를 사용하여 두 배열의 교차점을 얻습니다.
  2. 먼저 정렬한 다음 이중 포인터로 두 배열을 반복합니다.
  3. 처음에는 두 포인터가 각각 배열의 헤드를 가리킵니다. 한 번에 두 포인터의 두 숫자를 비교합니다.
    • 두 숫자가 같지 않으면 더 작은 숫자에 대한 포인터가 오른쪽으로 1만큼 이동하고,
    • 두 숫자가 같으면 해당 숫자를 답에 추가하고 두 포인터를 하나씩 오른쪽으로 이동합니다.
    • 하나 이상의 포인터가 배열의 경계를 초과하면 탐색이 종료됩니다.

복잡성

시간 복잡도 O(N)
공간 복잡도 O(|Σ|)

문제 해결 코드

솔루션 코드는 다음과 같습니다(코드의 자세한 설명).

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        // 1. 排序
        Arrays.sort(nums1);
        Arrays.sort(nums2);

        int length1 = nums1.length, length2 = nums2.length;
        int[] intersection = new int[Math.min(length1, length2)];
        int index1 = 0, index2 = 0, index = 0;
        // 2. 两个指针 index1, index2
        while(index1 < length1 && index2 < length2) {
            if (nums1[index1] < nums2[index2]) {
                index1++;
            } else if (nums1[index1] > nums2[index2]) {
                index2++;   
            } else {
                intersection[index] = nums1[index1];
                index1++;
                index2++;
                index++;
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }
}
复制代码

제출 후 피드백 결과(이 주제는 최적화되지 않았기 때문에 성능은 평균입니다):

이미지.png

참조 정보

추천

출처juejin.im/post/7085707726776434695