【LeetCode刷题】两个数组的交集 II


题目链接:350. 两个数组的交集 II

题目

给定两个数组,编写一个函数来计算它们的交集。

示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]

示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]

解题

两个数组,我首先想到了双指针法,可以看出数组时无序的,所以要想用双指针法,要先对数组排序,之后分从开头比较两个数组,相同则将数据加入到结果集,然后两个指针同时后移,不同则根据大小来判断移动哪一个指针,具体直接上代码吧。

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        List<Integer> res = new ArrayList<>(); // 结果集
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        for(int i=0, j=0; i<nums1.length && j<nums2.length;) {
            if(nums1[i] == nums2[j]) {
                res.add(nums1[i]);  // 加入结果集
                i++;
                j++;
            } else if(nums1[i] < nums2[j]) // 移动 i
                i++;
            else j++;  // 移动 j
        }

        int[] arr = new int[res.size()];
        for(int k=0; k<res.size(); k++)
            arr[k] = res.get(k);

        return arr;
    }
}

时间复杂度$$O(logn+n)$$

改进

指针划过之后,指针前面的数据就没有用处了,而且,交集中元素的个数一定是$$<=min{nums1.length, nums2.length}$$的,所以,我们可以选择其中一个数组来保存结果,最后截取结果部分即可。

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        // List<Integer> res = new ArrayList<>();
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int k = 0;
        for(int i=0, j=0; i<nums1.length && j<nums2.length;) {
            if(nums1[i] == nums2[j]) {
                nums1[k] = nums1[i]; // 用nums1保存结果
                i++;
                k++;
                j++;
            } else if(nums1[i] < nums2[j])
                i++;
            else j++;
        }

        return Arrays.copyOf(nums1, k); // java没有切片,这里复制好像还是要 k 个空间?
    }
}

声明:迟於|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 【LeetCode刷题】两个数组的交集 II


栖迟於一丘