Leetcode-350 两个数组的交集 II

作者: itbird01 | 来源:发表于2021-09-20 12:49 被阅读0次

    350. 两个数组的交集 II

    解题思路

    解法1--暴力解法

    1.题目中说明了‘我们可以不考虑输出结果的顺序’,也就是说不考虑两个数组的顺序,只考虑包含关系
    2.如果不考虑顺序,可以统计每个出现的数字的次数
    3.如果长数组中包含短数组中的数字,然后输出相应次数(短数组中数字出现的次数与长数组中数字出现的次数做笔记)的此数字即可

    解法2--使用哈希算法,考虑磁盘一次不可以全部读取

    1.遍历nums1,将key为每个出现的数字,value为每个数字出现的次数,这里有一个技巧,可以先遍历nums1和nums2较短数组
    2.遍历较长的数组,如果hashmap中已存在数字,则将其加入ans数组,并将出现的次数--,如果不存在则忽略

    解法3--如果数组已排序,可以使用双指针解法

    1.两个指针分别指向nums1、nums2头
    2.开始遍历,如果遇到相等,则加入结果数组,并且i++、j++;如果不等,则将较小的元素指针++,直到一方遍历到尾,结束遍历

    解题遇到的问题

    1.错误的解法(考虑了原数组每个数字出现的顺序),留作‘纪念’,谨记之后做题,一定要认真审题

    后续需要总结学习的知识点

    1.如果给定的数组已经排好序呢?你将如何优化你的算法?
    2.如果 nums1 的大小比 nums2 小很多,哪种方法更优?
    3.如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

    ##解法1
    class Solution {
    public static int[] intersect(int[] nums1, int[] nums2) {
            HashMap<Integer, Integer> nums2map = new HashMap<Integer, Integer>();
            HashMap<Integer, Integer> nums1map = new HashMap<Integer, Integer>();
            for (int i = 0; i < nums2.length; i++) {
                if (nums2map.containsKey(nums2[i])) {
                    nums2map.put(nums2[i], nums2map.get(nums2[i]) + 1);
                } else {
                    nums2map.put(nums2[i], 1);
                }
            }
    
            for (int i = 0; i < nums1.length; i++) {
                if (nums1map.containsKey(nums1[i])) {
                    nums1map.put(nums1[i], nums1map.get(nums1[i]) + 1);
                } else {
                    nums1map.put(nums1[i], 1);
                }
            }
    
            if (nums1map.size() > nums2map.size()) {
                return realIntersect(nums2map, nums1map);
            } else {
                return realIntersect(nums1map, nums2map);
            }
        }
    
        private static int[] realIntersect(HashMap<Integer, Integer> shortNums,
                HashMap<Integer, Integer> longNums) {
            List<Integer> maxList = new ArrayList<Integer>();
    
            Iterator<Integer> it = shortNums.keySet().iterator();
            while (it.hasNext()) {
                int key = it.next();
                int value = shortNums.get(key);
                if (longNums.containsKey(key)) {
                    int size = value > longNums.get(key)
                            ? longNums.get(key)
                            : value;
                    for (int i = 0; i < size; i++) {
                        maxList.add(key);
                    }
                }
            }
    
            int[] result = new int[maxList.size()];
            for (int i = 0; i < maxList.size(); i++) {
                result[i] = maxList.get(i);
            }
            return result;
        }
    }
    
    ##解法2
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    class Solution {
        public static int[] intersect(int[] nums1, int[] nums2) {
            // 遍历nums1,将key为每个出现的数字,value为每个数字出现的次数,这里有一个技巧,可以先遍历nums1和nums2较短数组
            HashMap<Integer, Integer> numsmap = null;
            if (nums1.length > nums2.length) {
                numsmap = insertHashMap(nums2);
            } else {
                numsmap = insertHashMap(nums1);
            }
    
            // 遍历较长的数组,如果hashmap中已存在数字,则将其加入ans数组,并将出现的次数--,如果不存在则忽略
            if (nums1.length > nums2.length) {
                return getResult(numsmap, nums1);
            } else {
                return getResult(numsmap, nums2);
            }
        }
    
        public static int[] getResult(HashMap<Integer, Integer> numsmap,
                int[] nums) {
            List<Integer> ansIntegers = new ArrayList<Integer>();
            for (int i = 0; i < nums.length; i++) {
                if (numsmap.containsKey(nums[i])) {
                    ansIntegers.add(nums[i]);
                    if (numsmap.get(nums[i]) == 1) {
                        numsmap.remove(nums[i]);
                    } else {
                        numsmap.put(nums[i], numsmap.get(nums[i]) - 1);
                    }
                }
            }
            int[] ans = new int[ansIntegers.size()];
            for (int i = 0; i < ansIntegers.size(); i++) {
                ans[i] = ansIntegers.get(i);
            }
            return ans;
        }
    
        public static HashMap<Integer, Integer> insertHashMap(int[] nums) {
            HashMap<Integer, Integer> numsmap = new HashMap<Integer, Integer>();
            for (int i = 0; i < nums.length; i++) {
                numsmap.put(nums[i], numsmap.getOrDefault(nums[i], 0) + 1);
            }
            return numsmap;
        }
    
    }
    
    ##解法3
    class Solution {
        public int[] intersect(int[] nums1, int[] nums2) {
            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;
            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);
        }
    }
    
    ##错误的解法(考虑了原数组每个数字出现的顺序)
    class Solution {
        public static int[] intersect(int[] nums1, int[] nums2) {
            if (nums1.length > nums2.length) {
                return realIntersect(nums2, nums1);
            } else {
                return realIntersect(nums1, nums2);
            }
        }
    
        private static int[] realIntersect(int[] shortNums, int[] longNums) {
            List<Integer> maxList = new ArrayList<Integer>();
            for (int i = 0; i < longNums.length; i++) {
                int k = i;
                List<Integer> list = new ArrayList<Integer>();
                for (int j = 0; j < shortNums.length; j++) {
                    if (k < longNums.length && shortNums[j] == longNums[k]) {
                        k++;
                        list.add(shortNums[j]);
                    }
                }
                if (k > i && list.size() > maxList.size()) {
                    maxList = list;
                }
            }
    
            int[] result = new int[maxList.size()];
            for (int i = 0; i < maxList.size(); i++) {
                result[i] = maxList.get(i);
            }
            return result;
        }
    }
    

    相关文章

      网友评论

        本文标题:Leetcode-350 两个数组的交集 II

        本文链接:https://www.haomeiwen.com/subject/lknfgltx.html