室友说二分查找做不来这题 我说来我做给你看 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关推荐
沙蒿同学8 分钟前
我把架构约定编译成了会变红的测试:Wails v2 + Go + Vue3 桌面脚手架实战
前端·后端·github
cpolar技术支持11 分钟前
本地 Playwright 测试报告怎么远程复盘?Trace Viewer 跑起来后,用 cpolar 分享失败现场
前端·自动化测试·测试工具·cpolar·playwright
wordbaby11 分钟前
企业级后台管理系统路由设计与最佳实践指南
前端
胡志辉的博客21 分钟前
【完全开源】IP 纯净度检测 可一键部署到自己的CF
前端·javascript·chrome·ip·chromium
Hilaku1 小时前
作为面试官,我最怕遇到什么样的候选人?
前端·javascript·程序员
TiDi1 小时前
Pinia优化重复请求
前端
web3d5201 小时前
01-用 Leafletjs 10 分钟搭一张水利一张图(Vue3 + Vite 实战)
前端·javascript
晚安日记wanna2 小时前
Vue2 的 defineProperty 差在哪四层追问筛掉九成候选人
前端·vue.js·面试
TiDi2 小时前
吸顶导航交互实现
前端
kisshyshy2 小时前
从Props透传到自定义Hook:系统梳理React跨层级通信与逻辑复用
前端·架构·代码规范