室友说二分查找做不来这题 我说来我做给你看 leetcode 350 两个数组的交集

用二分查找来做一个简单题 室友说做不了,我说行,我做给你看

哈喽哈喽,我是你们的金樽清酒,很高兴能把我自己学习的历程分享在网上,把自己学到的知识分享给大家,最近刚学了二分查找,室友说你不是刚学了二分查找嘛,我给你一道题,你能用二分写出两个测试用例嘛,这道题是用二分写不出来的,我看题解都没有二分。好,那我就写给他看。

先了解一下二分查找

二分查找是一个可以快速检索数组某元素下标的算法,在我往期的文章里面有(跟着代码随想录 一 二分查找 - 掘金 (juejin.cn))

先看一下题

给你两个整数数组 nums1nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

题目分析 以一个数组作为查询的数组,另一个数组里面的元素作为target,就可以用二分查找来写

js 复制代码
var intersect = function (nums1, nums2) {
    let arr = []
    nums1.sort((a, b) => a - b)
    nums2.sort((a, b) => a - b)
    if (nums1.length >= nums2.length) {
        for (let i = 0; i < nums2.length; i++) {
            if (erfen(nums1, nums2[i]) !== -1) {
                let index = erfen(nums1, nums2[i])
                arr.push(nums1[index])
                nums1.splice(index, 1)
            }
        }
        return arr
    } else
        if (nums1.length < nums2.length) {
            for (let i = 0; i < nums1.length; i++) {
                if (erfen(nums2, nums1[i]) !== -1) {
                    let index = erfen(nums2, nums1[i])
                    arr.push(nums2[index])
                    nums2.splice(index, 1)
                }
            }
            return arr
        }

};
function erfen(arr1, target) {
    let mid, left = 0
    let right = arr1.length - 1
    while (left <= right) {
        mid = left + ((right - left) >> 1)
        if (arr1[mid] > target) {
            right = mid - 1
        } else if (arr1[mid] < target) {
            left = mid + 1
        }
        else if (arr1[mid] == target) {
            return mid
        }
    }
    return -1
}

这是我写的代码,因为刚开始只是想通过两个用例,所以比较了数组长度,其实是没有必要的。 用二分查找找到下标,再把该下标的值push进新数组,然后删除掉,这是避免重复元素,存在重复元素二分查找会出问题,只能找到前面或后面。这样其实就可以了。

室友没有我写的那么复杂,可以优化的,删除重复元素后就没有必要比数组长短了。室友当时没有考虑删除元素的问题。

改进版

js 复制代码
var intersect = function (nums1, nums2) {
    nums2.sort((a, b) => a - b)
    nums1.sort((a, b) => a - b)
    let sum = []
    let left = 0

    for (let i = 0; i < nums1.length; i++) {
        let number = nums1[i]
        let right = nums2.length - 1
        while (left <= right) {
            let midle = Math.ceil((left + right) / 2)
            if (nums2[midle] > number) {
                right = midle - 1
            } else if (nums2[midle] < number) {
                left = midle + 1

            } else if (nums2[midle] === number) {
                let index = nums2.splice(midle, 1)
                
                sum.push(index)
                break
            }

        }
    }

    return sum
}

双指针法

js 复制代码
let intersect = function (nums1, nums2) {
    nums1.sort((a, b) => a - b);
    nums2.sort((a, b) => a - b);
    let l = 0, r = 0, ans = [];
    while (l < nums1.length && r < nums2.length) {
        if (nums1[l] === nums2[r]) {
            ans.push(nums1[l]);
            l++;
            r++;
        } else nums1[l] < nums2[r] ? l++ : r++;
    }
    return ans;
};

作者:御三五 🥇
链接:https://leetcode.cn/problems/intersection-of-two-arrays-ii/solutions/683821/ha-xi-biao-liang-ge-shu-zu-de-jiao-ji-ii-fkwo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关推荐
星就前端叭39 分钟前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
m0_7482345242 分钟前
前端Vue3字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
前端·webpack·node.js
Web阿成42 分钟前
3.学习webpack配置 尝试打包ts文件
前端·学习·webpack·typescript
噢,我明白了1 小时前
同源策略:为什么XMLHttpRequest不能跨域请求资源?
javascript·跨域
sanguine__1 小时前
APIs-day2
javascript·css·css3
jwensh2 小时前
【Jenkins】Declarative和Scripted两种脚本模式有什么具体的区别
运维·前端·jenkins
关你西红柿子2 小时前
小程序app封装公用顶部筛选区uv-drop-down
前端·javascript·vue.js·小程序·uv
益达是我2 小时前
【Chrome】浏览器提示警告Chrome is moving towards a new experience
前端·chrome
济南小草根2 小时前
把一个Vue项目的页面打包后再另一个项目中使用
前端·javascript·vue.js
小木_.2 小时前
【python 逆向分析某有道翻译】分析有道翻译公开的密文内容,webpack类型,全程扣代码,最后实现接口调用翻译,仅供学习参考
javascript·python·学习·webpack·分享·逆向分析