室友说二分查找做不来这题 我说来我做给你看 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 分钟前
Vue3中使用LogicFlow实现简单流程图
javascript·vue.js·流程图
YBN娜9 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=9 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck13 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!34 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。39 分钟前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning1 小时前
React.lazy() 懒加载
前端·react.js·前端框架