算法学习(四)查找问题

2023-11-18

一、查找问题通常有2类

1、查找有无 :元素a是否存在?set;集合
2、查找对应关系(键值对应):元素a出现了几次?map;字典

leetcode349. 两个数组的交集

给定两个数组,编写一个函数来计算它们的交集
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]

  • 在这里输出的每个元素只出现1次,只需要使用set这个数据结构就好了,只需要将nums1 放入set中,在查找nums2有没有相同的元素
import java.util.HashSet;
import java.util.Set;
class Solution {
        public int[] intersection(int[] nums1, int[] nums2) {
            Set<Integer> record = new HashSet<>();
        Set<Integer> result = new HashSet<>();
        for (int num : nums1) {
            record.add(num);
        }
        for (int num : nums2) {
            if (record.contains(num)) {
                result.add(num);
            }
        }
        int[] res = new int[result.size()];
        int i = 0;
        for (int num : result) {
            res[i] = num;
            i++;
        }
        return res;
        }
}

leetcode350. 两个数组的交集 II

给定两个数组,编写一个函数来计算它们的交集。
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]

  • 利用好map
import java.util.*;
class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Map<Integer, Integer> record = new HashMap<>();
        LinkedList<Integer> list = new LinkedList<Integer>();
        for (int i = 0; i < nums1.length; i++) {
            if (record.containsKey(nums1[i]))
                record.put(nums1[i], record.get(nums1[i]) + 1);
            else
                record.put(nums1[i], 1);
        }

        for (int j = 0; j < nums2.length; j++) {
            if (record.containsKey(nums2[j]) && record.get(nums2[j]) > 0) {
                list.add(nums2[j]); //添加到list中
                record.put(nums2[j], record.get(nums2[j]) - 1);
            }
        }

        int count = list.size();
        int[] aux = new int[count];
        for (int i = 0; i < count; i++) {
            aux[i] = list.get(i);
        }
        return aux;
    }
}

相关问题242,202,290,205,451

二、一个使用查找表的经典问题

leetcode1. 两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]
几种思路

  • 暴力解法O(n^2)
  • 排序后,对于有序数组,使用双索引对撞O(nlogn)+O(n)=O(nlogn)
  • 查找表,将所有元素仿佛查找表,对每个元素a查找target-a是否存在
import java.util.*;
public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> record = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int value = target - nums[i];//只将value前面的元素放入查找表中
            if (record.containsKey(value)) {//value前面的某个元素和value相等
                return new int[]{record.get(value), i};//找到解
            }
            record.put(nums[i], i);//如果查找失败就将value也纳入到查找表,
        }
        throw new IllegalArgumentException("No two sum solution");
    }

相关问题,15,18,16

三、灵活选择键值

leetcode454. 四数相加 II

给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。(所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500)
输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
输出:
2

  • 暴力解法O(n^4)
  • 将D中所有元素放入查找表,只要遍历ABC,O(n^3)
  • 将C+D的每一种可能放入查找表,O(n^2)
import java.util.*;
class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        //key,C+D的所有可能性,value是可能性出现的频率
        Map<Integer, Integer> record = new HashMap<>();
        for (int i = 0; i < C.length; i++) {
            for (int j = 0; j < D.length; j++) {
                int sum = C[i] + D[j];
                if (record.containsKey(sum)) {
                    record.put(sum, record.get(sum) + 1);
                } else {
                    record.put(C[i] + D[j], 1);
                }

            }
        }

        int count = 0;
        //记录A,B 任意组合的和的负值,然后在查找表中查找是否有对应的值
        for (int i = 0; i < A.length; i++) {
            for (int j = 0; j < B.length; j++) {
                int res = -(A[i] + B[j]);
                if (record.containsKey(res)) {
                    count += record.get(res);
                }
            }
        }

        return count;
    }
}

相关问题49

leetcode447. 回旋镖的数量

给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。(n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中)
输入:
[[0,0],[1,0],[2,0]]
输出:
2

  • 暴力解法O(n^3)
  • 观察到i是一个枢纽,对于每个点i,遍历其余点到i的距离,O(n^2)
    对于每个点i,设计出这样一张查找表,扫描一遍所有的其他点,计算出其他点到i的距离,在查找表中对应的键就是距离的值,对应的值就是有多少个这样的点

     

    查找表

import java.util.*;
class Solution {
    public int numberOfBoomerangs(int[][] points) {
        int res = 0;
        for (int i = 0; i < points.length; i++) {
            Map<Integer, Integer> record = new HashMap<>();//对于每个点i,都设置一个查找表,
            for (int j = 0; j < points.length; j++) {
                if (j != i) {
                    //找到了一个和i不同的点,计算距离
                    int distance = (points[i][0] - points[j][0]) * (points[i][0] - points[j][0]) +
                            (points[i][1] - points[j][1]) * (points[i][1] - points[j][1]);
                    res += record.getOrDefault(distance, 0) * 2;
                    record.put(distance, record.getOrDefault(distance, 0) + 1);
                }
            }
        }
        return res;
    }
}

相关问题149

四、查找表和滑动窗口

leetcode219. 存在重复元素 II

给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。
输入: nums = [1,2,3,1], k = 3
输出: true

  • 暴力解法O(n^2)
  •  

     

    滑动窗口思路,i和j在l到l+k区间内,这个区间有k+1个元素,在一个连续的有有k+1个元素的区间中,如果能找到2个元素他们的值相等,就能保证这两个元素的索引的差也一定是小于等于k的

    滑动窗口

    l+k区间

import java.util.*;
class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        Set<Integer> record = new HashSet<>();
        //在散列表中搜索当前元素,如果找到了就返回 true。
        //在散列表中插入当前元素。
        //如果当前散列表的大小超过了 kk, 删除散列表中最旧的元素。
        for (int i = 0; i < nums.length; i++) {
            if (record.contains(nums[i])) {
                return true;
            }
            record.add(nums[i]);
            if (record.size() == k + 1) {
                record.remove(nums[i - k]);
            }
        }
        return false;
    }
}

相关问题217

五、 二分搜索树底层实现的顺序性

leetcode220. 存在重复元素 III

给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。
输入: nums = [1,2,3,1], k = 3, t = 0
输出: true

import java.util.*;
class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        TreeSet<Integer> record = new TreeSet<>();

        for (int i = 0; i < nums.length; i++) {
            //找到当前元素的后继
            Integer s = record.ceiling(nums[i]);
            if (s != null && s <= nums[i] + t) {
                return true;
            }
            //找到当前元素的前身
            Integer g = record.floor(nums[i]);
            if (g != null && nums[i] <= g + t) {
                return true;
            }
            record.add(nums[i]);
            if (record.size() == k + 1) {
                record.remove(nums[i - k]);
            }
        }
        return false;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法学习(四)查找问题 的相关文章

随机推荐

  • Java之局部变量的作用域

    1 循环语句中变量 public static void main String args for int i 0 i lt 10 i int sum 3 System out println i sum 就上面最简单的程序说明吧 上面在f
  • 玻纤效应对skew的影响(三)

    玻纤效应对skew的影响 一 玻纤效应对skew的影响 二 对内skew对32Gbps NRZ和64Gbps PAM 4的影响 这一篇中 玻纤效应造成的对内skew将会加入到32Gbps NRZ和64Gbps PAM 4 SerDes全链路
  • 转载-浅析UDS诊断

    文章目录 前言 一 诊断和通信管理功能单元 0x10 DiagnosticSessionControl 0x11 ECUReset 0x27 SecurityAccess 0x28 CommunicationControl 0x3E Tes
  • maven工程编译生成source包

    开发Java服务端项目的时候 经常需要开发SDK作为依赖包提供给目标工程引用 但是目标工程在运行的调试的时候断点到依赖包里面的代码 由于依赖包的代码是编译后端class类 和源码有不少差异 不方便阅读 所以在开发的时候最好生成源码形式的依赖
  • Linux下Android Studio的安装步骤及关键点【整理】

    2013年google公司发布了一个新的Android集成开发环境 Android Studio 它为Android开发者提供了更多便利 而google慢慢地已经把重心放到Android Studio的开发上了 所以对于Android工程师
  • Allegro输出带等长规则的Excel操作指导

    Allegro输出带等长规则的Excel操作指导 Allegro可以输出带等长规则的Excel文件 方便检查和查阅 具体操作如下 打开规则管理器 选择Relative Propagation Delay 选择需要输出的match group
  • 如何清除SQL Server Management Studio的最近服务器列表

    SQL Server Management Studio SSMS 的 连接到服务器 对话框会记录用户所有访问过的服务器名称 这个功能对于经常连接多个数据库的人来说确实挺方便的 不过使用了一段时间之后 这个列表会变得很长 里面还有很多服务器
  • 利用原生js实现随机颜色画布

    这几天复习了一下js的DOM 文档对象模型 部分 看到鼠标事件的时候想到可以试着写一个js画布的案例 一 实现思路 1 利用js绑定鼠标按下事件 鼠标放开事件 在通过鼠标移动事件 获取鼠标所在位置 2 通过鼠标移动事件动态创建节点挂载到页面
  • 家庭实验室系列文章-电脑如何配置网络唤醒 (WOL)?

    前言 其实这个专题很久很久之前就想写了 但是一直因为各种原因拖着没动笔 因为没有资格 也没有钱在一线城市买房 但是在要结婚之前 婚房又是刚需 我和太太最终一起在一线城市周边的某二线城市买了房 再之后 一起装修 她负责非电相关 我负责电 网相
  • 字符串与数组的相互转换

    一 数组转字符串 arr join 指定符号 用指定符号把数组元素连接起来 返回连接好的字符串 let arr 1 2 3 4 arr join 1 2 3 4 arr join 1 2 3 4 二 字符串转数组 多个元素 str spli
  • Android NDK开发-环境搭建(一)

    一 概念 Android NDK Android Native Development Kit 简称NDK Android NDK 是一组允许您将 C 或 C 原生代码 嵌入到 Android 应用中的工具 能够在 Android 应用中使
  • python多进程原理及其实现

    文章目录 1 进程的基本概念 2 父进程和子进程 2 1 父子进程如何区分 2 2 子进程如何回收 3 Python进程模块 3 1 fork 3 2 Process进程 3 3 进程池POOL 多个进程 4 进程间通信方式 5 多进程实现
  • SOLOv2 学习笔记

    博客原文 https blog csdn net weixin 44270815 article details 105283301 模型下载教程 https blog csdn net weixin 44270815 article de
  • Win64安装cx_Oracle过程

    学习python过程中 因需要连接oracle数据库 所以要安装cx Oracle 我的电脑是WIN64 python是2 7版本 本地oracle client是32位的 安装过cx Oracle 5 2 1 11g win amd64
  • js实现word转化为html

  • windows8.1 vs2015 dlib库cpu 版本编译以及应用 library is 90, caller expects 80

    近期由于要做一个关于人脸计数的项目 因此对dlib库进行了编译和使用 其中遇到了不少问题 下面请听我一一道来 第一步 从dlib官网下载dlib源码 链接地址 https github com davisking dlib 第二步 采用cm
  • PrimeTime中的DMSA

    第一次尝试使用PT的DMSA 步骤存在太多的弯弯绕绕了 这里记录一下 一 什么是DMSA 在PT中 我们将一种operating mode 如FUNC DFT等 和一种operating condition 如WC WCZ AVS等 的组合
  • SQLDEVELOPER启动警告 - 无法安装某些模块: oracle.jewt_core - org.netbeans.InvalidException: Netigso

    https bbs csdn net topics 390721236 page 1 SQL Developer第一次启动后没问题 但是第二次启动后就报错 根据如下步骤可以解决 1 Go to C Users USERNAME AppDat
  • C#操作MongoDB,看我这一篇就够了!

    一 准备工作 工欲善其事必先利其器 首先呢咱们得下载好C 程序里面可以驱动mongodb的组件 走起官网 C 操作mongodb组件下载 菜鸟教程也上一上 mongodb菜鸟教程 dll下载下来之后有这几个 都引用上 不要省 哈哈 个人还是
  • 算法学习(四)查找问题

    一 查找问题通常有2类 1 查找有无 元素a是否存在 set 集合 2 查找对应关系 键值对应 元素a出现了几次 map 字典 leetcode349 两个数组的交集 给定两个数组 编写一个函数来计算它们的交集 输出结果中的每个元素一定是唯