室友说二分查找做不来这题 我说来我做给你看 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关推荐
卢叁4 分钟前
Flutter之路由监听器
前端·flutter
三翼鸟数字化技术团队8 分钟前
2025前端技术趋势:从智能到沉浸的新时代
前端·ai编程
恋猫de小郭10 分钟前
Android 17 有什么需要适配的?2026 Android 禁止侧载又是什么?
android·前端·flutter
Never_Satisfied14 分钟前
在HTML & CSS中,如何计算CSS特异性
前端·css·html
滕青山17 分钟前
网页源代码查看在线工具 核心JS实现
前端·javascript·vue.js
www_stdio19 分钟前
项目基础准备之Zustand:轻量级 React 状态管理的优雅之选
前端·react.js·typescript
躲在云朵里`23 分钟前
同一账号在同一客户端类型只能登录一次
前端·spring·bootstrap
敲敲了个代码27 分钟前
构建工具的第三次革命:从 Rollup 到 Rust Bundler,我是如何设计 robuild 的
开发语言·前端·javascript·后端·rust
加个鸡腿儿27 分钟前
Nuxt SSR 水合错误处理实践:响应式布局的正确姿势
前端·typescript·nuxt.js
奋斗吧程序媛28 分钟前
使用代理服务器的方式解决跨域问题
前端·javascript·vue.js