室友说二分查找做不来这题 我说来我做给你看 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关推荐
恋猫de小郭3 分钟前
Flutter 开发怎么做 Agent ?从工程实战详细给你解读下
android·前端·flutter
IT_陈寒5 分钟前
React状态更新延迟搞晕我,原来是闭包在捣鬼
前端·人工智能·后端
晓得迷路了6 分钟前
栗子前端技术周刊第 136 期 - pnpr、Flow 重构移植 Rust、Astryx...
前端·javascript·css
Mr.Daozhi15 分钟前
从零构建 AI 学术论文助手(四):PDF.js 实时截图 + Gemini 视觉分析
javascript·人工智能·pdf·canvas·pdf.js·gemini
柳杉19 分钟前
别再手写大屏了!用这套「3D 地图 + 拖拽脚手架」示例源码,交付效率提升 80%
前端·three.js·数据可视化
乌夷28 分钟前
Vue.js 3 的设计思路
前端·javascript·vue.js
丨我是张先生丨1 小时前
英语单词 Web Page
前端·css·css3
随风一样自由1 小时前
【前端+Vitest测试框架】Vitest | Playwright | WebdriverIO | Preview
前端·前端框架·可用性测试
前端之虎陈随易10 小时前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·vue.js·人工智能·typescript·node.js
一路向北he10 小时前
字节钢铁军团--“提供情境,而非控制”
java·开发语言·前端