每日一题-数组 leetcode350

189 阅读2分钟

一、题目描述

二、题目思路

  1. hashmap可以存储 不重复的元素
  2. 存储nums1数组所有元素,遍历nums2数组所有元素,出现重复元素即添加进集合中,并更新重复元素对应的value值

三、提交代码

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        HashMap<Integer,Integer> hashMap = new HashMap<>();
        for(int i =0;i<nums1.length;i++){
            hashMap.put(nums1[i],hashMap.getOrDefault(nums1[i],0)+1);
        }
        ArrayList<Integer> list = new ArrayList<>();
        for(int i=0;i<nums2.length;i++){
            if(hashMap.containsKey(nums2[i])&&hashMap.get(nums2[i])>0){
                list.add(nums2[i]);
                hashMap.put(nums2[i],hashMap.get(nums2[i])-1);
            }
        }
        int[] result = new int[list.size()];
        for(int i =0;i<list.size();i++){
            result[i] = list.get(i);
        }
        return result;
    }
}

四、存在的问题

  1. 时间复杂度为O(n+m)
  2. 空间复杂度为O(n)
  3. 提交的代码中,如果n>m,则浪费多余的存储空间,因此 可以优化代码在程序开头:
if(nums1.length>nums2.length){
    return intersect(nums2,nums1);
}
HashMap<Integer,Integer> hashMap = new HashMap<>();
...

五、关于进阶问题

以上解法即进阶问题二的答案

针对问题一:

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int i =0;
        int j =0;
        int k =0;
        ArrayList<Integer> list = new ArrayList<>();
        while(i<nums1.length&&j<nums2.length){
            if(nums1[i]<nums2[j]){
                i++;
            }else if(nums1[i]>nums2[j]){
                j++;
            }else{
                list.add(nums1[i]);
                i++;
                j++;
            }
        }
        int[] result = new int[list.size()];
        for(int a:list){
            result[k] = a;
            k++;
        }
        return result;
    }
}

对于问题一,由于数组已经排序完成,因此可以使用两个指针进行判断,排序后的数组存在大小关系,方便对指针进行操作

时间复杂度为O(nlogn+mlogm),包括对数组进行排序,以及线性扫描

空间复杂度是O(1),主要开辟了存储答案的空间

针对问题二:

可以考虑提交代码的方法

针对问题三:

对应进阶问题三,如果内存十分小,不能使用空间复杂度高的算法

针对排序算法,一般说排序算法都是针对于内部排序,一旦涉及到跟磁盘打交道(外部排序),归并排序是天然适合外部排序的算法,可以将分割后的子数组写到单个文件中,归并时将小文件合并为更大的文件。当两个数组均排序完成生成两个大文件后,即可使用双指针遍历两个文件,如此可以使空间复杂度最低。