哈希表与统计——594、350、554、609、454(2简3中)

news2024/9/23 23:22:17

594. 最长和谐子序列(简单)

和谐数组是指一个数组里元素的最大值和最小值之间的差别 正好是 1 。

现在,给你一个整数数组 nums ,请你在所有可能的子序列中找到最长的和谐子序列的长度。

数组的子序列是一个由数组派生出来的序列,它可以通过删除一些元素或不删除元素、且不改变其余元素的顺序而得到。

解法一、哈希统计

如果不存在键,放入1。如果存在键,更新数量。如果存在num+1或者-1的键,更新最大值。

class Solution {
    public int findLHS(int[] nums) {
        HashMap<Integer,Integer> hm = new HashMap<>();
        int max = 0;
        for(int num : nums){
            if(!hm.containsKey(num)){
                hm.put(num,1);
            }else{
                hm.put(num,hm.get(num) + 1);
            }
            if(hm.containsKey(num+1)){
                max = Math.max(max,hm.get(num) + hm.get(num+1));
            }
            if(hm.containsKey(num-1)){
                max = Math.max(max,hm.get(num) + hm.get(num-1));
            }
        }
        return max;
    }
}

 

解法二、排序+滑动窗口

滑窗和双指针做法到底什么差别orzzzz

class Solution {
    public int findLHS(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length, ans = 0;
        for (int i = 0, j = 0; j < n; j++) {
            while (i < j && nums[j] - nums[i] > 1) i++;
            if (nums[j] - nums[i] == 1) ans = Math.max(ans, j - i + 1);
        }
        return ans;
    }
}


350. 两个数组的交集 II(简单)

给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。 

解法一、排序

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        List<Integer> res = new LinkedList<>();
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int i = 0,j = 0;
        int n1 = nums1.length,n2 = nums2.length;
        while(i < n1 && j < n2){
            while(i < n1 && j < n2&& nums1[i] < nums2[j])i++;
            while(i < n1 && j < n2 && nums1[i] > nums2[j])j++;
            while(i < n1 && j < n2 && nums1[i] == nums2[j]){
                res.add(nums1[i]);
                i++;
                j++;
            }
        }
        int[] r = new int[res.size()];
        for(int k = 0;k < res.size();k++){
            r[k] = res.get(k);
        }
        return r;
    }
}

 

 解法二、哈希

不过其实感觉如果是哈希的话,直接用数组(桶计数)就挺好的,遍历一个++,遍历另一个--

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            return intersect(nums2, nums1);
        }
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int num : nums1) {
            int count = map.getOrDefault(num, 0) + 1;
            map.put(num, count);
        }
        int[] intersection = new int[nums1.length];
        int index = 0;
        for (int num : nums2) {
            int count = map.getOrDefault(num, 0);
            if (count > 0) {
                intersection[index++] = num;
                count--;
                if (count > 0) {
                    map.put(num, count);
                } else {
                    map.remove(num);
                }
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/intersection-of-two-arrays-ii/solutions/327356/liang-ge-shu-zu-de-jiao-ji-ii-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

554. 砖墙(中等)

你的面前有一堵矩形的、由 n 行砖块组成的砖墙。这些砖块高度相同(也就是一个单位高)但是宽度不同。每一行砖块的宽度之和相等。

你现在要画一条 自顶向下 的、穿过 最少 砖块的垂线。如果你画的线只是从砖块的边缘经过,就不算穿过这块砖。你不能沿着墙的两个垂直边缘之一画线,这样显然是没有穿过一块砖的。

给你一个二维数组 wall ,该数组包含这堵墙的相关信息。其中,wall[i] 是一个代表从左至右每块砖的宽度的数组。你需要找出怎样画才能使这条线 穿过的砖块数量最少 ,并且返回 穿过的砖块数量 。

解法一、哈希表

本质上还是统计题。需要转化思维,算穿过的砖最少,也就是算穿过缝隙最多。例如,对于用例

wall = [[1,2,2,1],[3,1,2],[1,3,2],[2,4],[3,1,2],[1,3,1,1]]

相当于统计1/3/5/6 、 3/4/6 、 1/4/6 、 2/6 、 3/4/6 、 1/4/5/6 中除了6以外,哪个数字出现最多,这个数字也就是代码里面的max。要注意对于不在边缘划线的条件,需要通过哈希表移除最大值的方式达到,而不能在最后的for循环里设置if。

此外有个细节:多写一个循环遍历哈希表值里最大值,比在第一个for里算要快。

class Solution {
    public int leastBricks(List<List<Integer>> wall) {
        int num = wall.size();
        int max = 0,sum = 0;
        HashMap<Integer,Integer> hm = new HashMap<>();
        for(List<Integer> bricks : wall){
            sum = 0;
            for(int brick : bricks){
                sum+=brick;
                if(!hm.containsKey(sum)){
                    hm.put(sum,1);
                }else{
                    hm.put(sum,hm.get(sum) + 1);
                }
            }
        }
        hm.remove(sum);
        for(int t : hm.values()){
            max = Math.max(max,t);
        }
        return num - max;
    }
}

 

 
609. 在系统中查找重复文件(中等)

给你一个目录信息列表 paths ,包括目录路径,以及该目录中的所有文件及其内容,请你按路径返回文件系统中的所有重复文件。答案可按 任意顺序 返回。

一组重复的文件至少包括 两个 具有完全相同内容的文件。

输入 列表中的单个目录信息字符串的格式如下:

  • "root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"

这意味着,在目录 root/d1/d2/.../dm 下,有 n 个文件 ( f1.txtf2.txt ... fn.txt ) 的内容分别是 ( f1_contentf2_content ... fn_content ) 。注意:n >= 1 且 m >= 0 。如果 m = 0 ,则表示该目录是根目录。

输出 是由 重复文件路径组 构成的列表。其中每个组由所有具有相同内容文件的文件路径组成。文件路径是具有下列格式的字符串:

  • "directory_path/file_name.txt"

 解法一、哈希

(备注写在前面)官方做法里的键值对是String--List<String>

遍历给的字符串组,对于每一个固定的字符串,用空格分割。此时的temp[0]是地址,之后的都是文件名和内容。把内容context作为键存入哈希,值则是对应的list中下标,方便每个文件找到自己在res中的位置。

这里有一个问题:如果重复时再存的话,第一次重复需要存两个,其余只需要存一个。所以不妨逆向思维,先把所有的都存进去,再删去不重复的(即size == 1)。

但是,尤其对于size == 1情况下的删除细节,也出过很多问题。最初时尝试了for的int i循环,但由于一边遍历一边删,它的size很快就变小了,也就是会访问过界。第二次时尝试了for-each循环,结果报错java.util.ConcurrentModificationException

        for(List<String> list : res){
            if(list.size() == 1)res.remove(list);
        }

 经检查,发现是遍历器和remove的删除问题,事故原因溯至轮子(源码)的某个值更新出现差错。于是再进行优化。解决方法有两种,两种都依旧是for的int i循环①每次删除操作后,i--②从后往前遍历。

class Solution {
    public List<List<String>> findDuplicate(String[] paths) {
        List<List<String>> res = new LinkedList<>();
        HashMap<String,Integer> hm = new HashMap<>();
        for(String s : paths){
            String[] temp = s.split(" ");
            for(int i = 1;i < temp.length;i++){
                String context = temp[i].substring(temp[i].indexOf('(')+1);
                StringBuilder sb = new StringBuilder();
                sb.append(temp[0]).append('/').append(temp[i].substring(0,temp[i].indexOf('(')));
                if(hm.containsKey(context)){//如果已经存在
                    res.get(hm.get(context)).add(sb.toString());//取出对应
                }else{//放进去
                    hm.put(context,res.size());
                    List<String> tempList = new LinkedList<>();
                    tempList.add(sb.toString());
                    res.add(tempList);
                }
            }
        }
         for(int i = res.size()-1;i >= 0;i--){
            if(res.get(i).size() == 1)res.remove(i);
        }
        return res;
    }
}

454. 四数相加 II(中等)

给你四个整数数组 nums1nums2nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

解法一、哈希

两两分组判断,时间复杂度O(n^2)

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        HashMap<Integer,Integer> hm = new HashMap<>();
        int res = 0;
        for(int num1 : nums1){
            for(int num2 : nums2){
                int sumAB = num1 + num2;
                if(!hm.containsKey(sumAB)){
                    hm.put(sumAB,1);
                }else{
                    hm.put(sumAB,hm.get(sumAB)+1);
                }
            }
        }
        for(int num3 : nums3){
            for(int num4 : nums4){
                int sumCD = -num3-num4;
                if(hm.containsKey(sumCD)){
                    res+= hm.get(sumCD);
                }
            }
        }
        return res;
    }
}

 

解法二、桶排序

时间复杂度差太多了。。第一个for循环之前确认范围,第一个for循环统计数量,第二个for循环查找符合条件的数量并加入res。原理没变,数据结构优化了

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int[] n1 = getMaxMin(nums1);
        int[] n2 = getMaxMin(nums2);
        int[] n3 = getMaxMin(nums3);
        int[] n4 = getMaxMin(nums4);
        int maxSum = Math.max(n1[0] + n2[0], -n3[1] - n4[1]);
        int minSum = Math.min(n1[1] + n2[1], -n3[0] - n4[0]);
        int[] map = new int[maxSum - minSum + 1];
        for (int i : nums1) {
            for (int j : nums2) {
                map[i + j - minSum] ++ ;
            }
        }
        int count = 0;
        for (int i : nums3) {
            for (int j : nums4) {
                count += map[- i - j - minSum];
            }
        }
        return count;
    }
    public int[] getMaxMin (int[] nums) {
        int[] num = Arrays.copyOf(nums, nums.length);
        Arrays.sort(num);
        int min = num[0];
        int max = num[nums.length - 1];
        return new int[] {max, min};
    }
}

 


碎碎念

  • 594重要的思路转换——能够删除任何数,就是能够选择任何想要的数。滑动窗口很有意思,虽然没搞懂和双指针根本上的差别。应该只是基于双指针实现?这附近埋个思考。
  • 554的思路转换很有意思。技术力感觉还好,配得上中等题。
  • 609写起来太冗余复杂了,但是也很有趣。确实感觉到细节处理能力上升了,而且一开始打好代码框架确实很重要
  • 454看了下题解才学会二二分组来着。
  • 其实还有个18,但是太难了,今天没睡午觉有点困,不想做。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2105431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华大HC32F460移植FreeRTOS

参考&#xff1a; 关于MCU M4内核移植FreeRTOS的笔记 主要参考这位大佬的&#xff0c;照做就行了&#xff0c;用的也是IAR HC32F460 freeRTOS移植 这位是用Keil的 MCU&#xff1a;华大HC32F460 库版本&#xff1a;hc32f460_ddl_Rev2.2.0 IDE&#xff1a; IAR FreeRTOS版本&…

【多线程】概述

进程与线程 概述 一个正在运行过程中的程序&#xff0c;就是一个进程&#xff0c;也称一个任务。进程是一个重要的软件资源&#xff0c;是由操作系统内核管理和组织的。 并行&#xff1a;微观上同一个时刻&#xff0c;两个核心上的进程&#xff0c;就是同时进行的。 并发&…

遗传算法Github初学

遗传算法的理论是根据达尔文进化论而设计出来的算法&#xff1a;人类是朝着好的方向&#xff08;最优解&#xff09;进化&#xff0c;进化过程中&#xff0c;会自动选择优良基因&#xff0c;淘汰劣等基因 遗传算法&#xff08;genetic algorithm——GA&#xff09;是计算数学中…

【JavaScript】LeetCode:11-15

文章目录 11 最长连续序列12 移动零13 盛最多水的容器14 三数之和15 接雨水 11 最长连续序列 数组排序、去重遍历数组中的元素&#xff0c;当元素连续时&#xff0c;长度加1&#xff0c;当不连续时&#xff0c;长度设置为1。 /*** param {number[]} nums* return {number}*/ v…

AI科学家:自动化科研的未来之路

随着人工智能&#xff08;AI&#xff09;技术的不断进步&#xff0c;AI已经在众多领域中展现了强大的潜力&#xff0c;尤其是在科研方面的应用正在引起广泛关注。最近&#xff0c;Sakana AI与牛津大学和不列颠哥伦比亚大学联合推出了一款被称为“AI科学家”的自动化科研工具&am…

第4章-01-学会从Chrome浏览器中Network

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年CSDN全站百大博主。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于专栏:Web爬虫入门与实战精讲,后续完整更新内容如下。 文章…

【Canvas与纹饰】环形小蜜蜂纹饰

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>环形小蜜蜂纹饰</title><style type"text/css"&g…

Mysql基础练习题 1378.使用唯一标识符替换员工ID (力扣)

1378. 展示每位用户的 唯一标识码&#xff08;unique ID &#xff09;&#xff1b;如果某位员工没有唯一标识码&#xff0c;使用 null 填充即可。 你可以以任意顺序返回结果表。 题目链接&#xff1a; https://leetcode.cn/problems/replace-employee-id-with-the-unique-i…

k8s调度、污点、容忍、不可调度、排水、数据卷挂载

一、Kubernetes的list-watch机制 1、List-watch K8S集群中&#xff0c;通过List-watch机制进行每个组件的协作&#xff0c;保持数据同步。这种设计可以实现每个组件之间的解耦 kubectl配置文件&#xff0c;统一向集群内部apiserver发送命令——通过apiserver把命令发送到各个…

C# 不安全代码

当一个代码块使用 unsafe 修饰符标记时&#xff0c;C# 允许在函数中使用指针变量。不安全代码或非托管代码是指使用了指针变量的代码块。 指针变量 指针 是值为另一个变量的地址的变量&#xff0c;即&#xff0c;内存位置的直接地址。就像其他变量或常量&#xff0c;您必须在…

【系统架构设计师-2022年】综合知识-答案及详解

文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6~7题】【第8题】【第9题】【第10题】【第11~12题】【第13题】【第14题】【第15题】【第16题】【第17~18题】【第19题】【第20题】【第21题】【第22题】【第23题】【第24题】【第25题】【第26题】【第27题】【第28题…

力扣刷题(复习版2)

题目&#xff1a; 计数质数 原题链接&#xff1a; 计数质数 题解 public int countPrimes(int n) {if (n < 2) return 0;// boolean 数组&#xff0c;初始时假设所有数都是质数boolean[] isPrime new boolean[n];Arrays.fill(isPrime, true); // 全部初始化为true// 从 …

网页版修改本地数据器:重新布局,引入 highlight.js高亮显示代码

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>修改数据器</title><!-- 引入 highlight.js 的 CSS 文件 --><link rel"stylesheet" href"https://cdnjs.cloudflare.…

Tauri应用开发实践指南(4)— Tauri 原生能力

本文首发于微信公众号&#xff1a;前端徐徐。欢迎关注&#xff0c;获取更多前端技能分享。 原生能力简介 Tauri 是一个用于构建安全的小型桌面应用程序的框架,它结合了 Web 前端和系统后端技术。Tauri 提供了一些原生能力,让您的 Web 应用程序能够访问本地系统资源和 API,主要…

聚焦新能源未来,望繁信科技邀您共赴CNDS 2024中国新能源产业数智峰会

在全球能源转型的关键时刻&#xff0c;新能源产业正以迅猛的速度向前发展&#xff0c;而数字化技术则为这一产业注入了前所未有的动力。为进一步推动新能源产业与数字化的深度融合&#xff0c;CNDS 2024中国新能源产业数智峰会即将于2024年9月13日在北京盛大举行。作为大数据流…

节日庆典中的白酒文化,传承与创新并存

在中华五千年的文明长河中&#xff0c;白酒文化如同一颗璀璨的明珠&#xff0c;熠熠生辉。它既是历史的见证者&#xff0c;也是文化的传承者。在节日庆典的喜庆氛围中&#xff0c;白酒更是不可或缺的元素&#xff0c;其背后蕴藏着深厚的文化底蕴和时代价值。豪迈白酒&#xff0…

The Llama 3 Herd of Models【论文原文下载】

关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 The Llama 3 Herd of Models【论文原文】 点击下载&#xff1a;原文下载链接 摘要 现代人工智能&#xff08;AI&#xff09;系统由基础模型驱动。本文介绍了一组新的基础模型&#xff0c;称为 Llama 3。它是…

Anaconda最新安装教程

1 概述 1 介绍 Anaconda是一个专注于数据分析的Python发行版本&#xff0c;它为科学计算和数据科学领域提供了强大的支持。Anaconda是一个开源的Python发行版&#xff0c;包含了conda、Python以及超过190个科学包及其依赖项。这些包涵盖了数据分析、机器学习、深度学习等多个…

突破视觉理解极限,Qwen2-VL重磅登场

前沿科技速递&#x1f680; 经过近一年的持续努力&#xff0c;Qwen团队宣布推出最新一代的视觉语言模型&#xff1a;Qwen2-VL。基于Qwen2的基础&#xff0c;Qwen2-VL在多个方面实现了显著提升&#xff0c;相较于前代模型Qwen-VL&#xff0c;它具备以下核心优势&#xff1a; 1. …

24/9/3算法笔记 kaggle泰坦尼克

题目&#xff1a; 这次我用两种算法做了这道题 逻辑回归二分类算法 import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.metr…