【算法刷题】Day15

news2024/11/25 12:34:38

文章目录

  • 1. 串联所有单词的子串
    • 题干:
    • 算法原理
    • 代码:
  • 2. 最小覆盖子串
    • 题干:
    • 算法原理:
      • 1、暴力枚举 + 哈希表
      • 2、滑动窗口 + 哈希表
    • 代码:

1. 串联所有单词的子串

在这里插入图片描述
在这里插入图片描述
原题链接


题干:

给定⼀个字符串 s 和⼀个字符串数组 words
words 中所有字符串 长度相同
s 中的 串联⼦串 是指⼀个包含 words中所有字符串以任意顺序排列连接起来的⼦串
、


算法原理

这道题和 Day14 中 所写的找到字符串所有字母异位词 很像
找到字符串所有字母异位词

因为 words 中所有字符串 长度相同
所以我们就可以把每一个字符串划分为长度相等的小字符串
并且用别的字母代替

s 中我们也可以根据相同的长度进行划分
这样我们对题目就进行了转化

在这里插入图片描述
不过在解题方面有些许的不同:

  1. 哈希表
    需要使用键值对的方式进行存储
    Map<String, Integer>
  2. left 和 right 指针的移动
    移动的步长是每个单词的长度(len)
  3. 划分窗口的执行次数
    由于 s 可以进行不同的划分
    我们就可以划分成 len 次

代码:

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> ret = new ArrayList<Integer>();
        Map<String, Integer> hash1 = new HashMap<String, Integer>();//保存字典中所有单词的频次
        for(String str : words) {
            hash1.put(str, hash1.getOrDefault(str, 0) + 1);
        }

        int len = words[0].length();
        int m = words.length;
        for(int i = 0; i < len; i++) {
            Map<String, Integer> hash2 = new HashMap<String, Integer>();//保存窗口内所有单词的频次
            for(int left = i, right = i, count = 0; right + len <= s.length(); right += len) {
                //进窗口 + 维护 count
                String in = s.substring(right, right+len);
                hash2.put(in, hash2.getOrDefault(in, 0) + 1);
                if(hash2.get(in) <= hash1.getOrDefault(in, 0)) {
                    count++;
                }
                //判断
                if(right - left + 1 > len * m) {
                    //出窗口 + 维护 count
                    String out = s.substring(left, left + len);
                    if(hash2.get(out) <= hash1.getOrDefault(out, 0)) {
                    	count--;
                	}
                    hash2.put(out, hash2.get(out) - 1);
                    left += len;
                }
                //更新结果
                if(count == m) {
                    ret.add(left);
                }
            }
        }
        return ret;
    }
}

在这里插入图片描述

2. 最小覆盖子串

在这里插入图片描述
在这里插入图片描述
原题链接

题干:

有字符串 s 和 t
返回 s 中涵盖 t 中所有字符串的最小子串
寻找的子字符串不少于该字符数量
在这里插入图片描述


算法原理:

1、暴力枚举 + 哈希表

在这里插入图片描述

2、滑动窗口 + 哈希表

在这里插入图片描述
在暴力解法中,left++,right 需要返回原来重新遍历

那么right 是否需要回去呢?
left++ 后有以下两种情况:

  1. 依然符合要求,这个时候 right 不用动
  2. 不符合要求,这个时候 right 向后移动

这个时候,我们就可以使用滑动窗口来解决问题
在这里插入图片描述

  1. left = 0 ,righ = 0
  2. 进窗口 hash1[ in ]++
  3. 判断 check[ hah1,hash2 ]
    更新结果 更新起始位置 和 最短长度
    出窗口 hash2[ out ]–

优化:
我们可以优化判断条件

使用 count 标记有效字符的种类
如果hash2 中 A 的个数 = hash1 中 A 的个数才算有效

  1. 进窗口 进之后判断 hash2[ in ] == hash1[ in ],count++
  2. 出窗口 出之前判断 hash2[ out ] == hash1[ out ],count–
  3. 判断条件 count == hash1.size()

代码:

class Solution {
    public String minWindow(String ss, String tt) {
        char[] s = ss.toCharArray();
        char[] t = tt.toCharArray();

        int[] hash1 = new int[128];//数组模拟哈希表 统计 t 中字符出现的频次
        int kinds = 0;//字符 t 中,有多少种字符
        for(char ch : t) {
            if(hash1[ch] == 0) {
                kinds++;
            }
            hash1[ch]++;
        }

        int[] hash2 = new int[128];//统计窗口中字符的频次

        int minlen = Integer.MAX_VALUE;
        int begin = -1;
        for(int left = 0,right = 0, count = 0; right < s.length; right++) {
            char in = s[right];
            hash2[in]++;//进窗口 + 维护chount
            if(hash2[in] == hash1[in]) {
                count++;
            }
            while(kinds == count) {//判断
                if(right - left + 1 < minlen) {//更新结果
                    begin = left;
                    minlen = right - left + 1;
                }
                char out = s[left++];
                if(hash2[out] == hash1[out]) {//出窗口 + 维护count
                    count--;
                }
                hash2[out]--;
            }
        }
        if(begin == -1) {
            return new String();
        }else {
            return ss.substring(begin, begin + minlen);
        }
    }
}

在这里插入图片描述

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

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

相关文章

Vue学习计划-Vue2--VueCLi(八)vuex统一状态管理实现数据共享

1. vuex是什么 概念&#xff1a;专门在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xff0c;对Vue应用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&#xff0c;且适用于任意组件间通信…

了解葡萄酒最重要的是什么?

事实上&#xff0c;大多数人只知道葡萄酒是一种酒精饮料味道很好&#xff0c;是您享用食物和营造氛围的完美饮品。但我认为知道得多一点葡萄酒的知识会增加你的欣赏力&#xff0c;你不必搜索葡萄酒来找寻资料&#xff0c;因为标签上有很多信息。 葡萄酒标签里有什么&#xff1f…

WinSCP显示服务器隐藏的文件

正常情况下&#xff0c;如果我们有使用WinSCP作为SFTP、FTP管理主机空间的时候&#xff0c;如果有类似.htaccess或者其他.开头或者其他特殊文件名扩展会直接看不到而是隐藏着的。这样就显得比较麻烦&#xff0c;自己都不知道有还是没有&#xff0c;比如我们要修改.htaccess伪静…

Kotlin 笔记 -- Kotlin 语言特性的理解(一)

函数引用、匿名函数、lambda表达式、inline函数的理解 双冒号对函数进行引用的本质是生成一个函数对象只有函数对象才拥有invoke()方法&#xff0c;而函数是没有这个方法的kotlin中函数有自己的类型&#xff0c;但是函数本身不是对象&#xff0c;因此要引用函数类型就必须通过双…

社交网络分析4(上):社交网络链路预测分析、Logistic回归模型、LLSLP方法(LightGBM 堆叠链路预测)、正则化方法、多重共线性

社交网络分析4 写在最前面社交网络链路预测分析概述链路预测分析简介链路预测分析的重要性社交网络链路预测分析方法基于网络结构的方法基于节点属性的方法基于随机游走的方法基于深度学习的方法 基于相似性和基于似然性的链路预测方法基于相似性的方法基于邻居的方法基于路径的…

【工具使用-有道云笔记】如何在有道云笔记中插入目录

一&#xff0c;简介 本文主要介绍如何在有道云笔记中插入目录&#xff0c;方便后续笔记的查看&#xff0c;供参考。 二&#xff0c;具体步骤 分为两个步骤&#xff1a;1&#xff0c;设置标题格式&#xff1b;2&#xff0c;插入标题。非常简单~ 2.1 设置标题格式 鼠标停在标…

【深度学习目标检测】八、基于yolov5的抽烟识别(python,深度学习)

YOLOv5是目标检测领域一种非常优秀的模型&#xff0c;其具有以下几个优势&#xff1a; 1. 高精度&#xff1a;YOLOv5相比于其前身YOLOv4&#xff0c;在目标检测精度上有了显著的提升。YOLOv5使用了一系列的改进&#xff0c;如更深的网络结构、更多的特征层和更高分辨率的输入图…

硬件基础-电阻

电阻 1.品牌 厚声、风华&#xff0c;三星、罗姆、松下、KOA 2.分类 插件 碳膜电阻&#xff1a;精度-5 J 是在高阻&#xff0c;高压和高温应用中 属负温度系数电阻 金属膜&#xff1a;-1 F 贴片 电阻标识&#xff1a;&#xff08;含义&#xff1a;阻值大小和精度&a…

使用DETR 训练VOC数据集和自己的数据集

一、数据准备 DETR用的是COCO格式的数据集。 如果要用DETR训练自己的数据集&#xff0c;直接利用Labelimg标注成COCO格式。如果是VOC数据集的话&#xff0c;要做一个格式转换&#xff0c;yolo格式的数据集&#xff0c;转换成coco格式 COCO数据集的格式类似这样&#xff0c;a…

【改进YOLOv8】磁瓦缺陷分类系统:改进LSKNet骨干网络的YOLOv8

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 近年来&#xff0c;随着智能制造产业的不断发展&#xff0c;基于人工智能与机器视觉的自动化产品缺陷检测技术在各行各业中得到了广泛应用。磁瓦作为永磁电机的主…

verilog基础语法-计数器

概述&#xff1a; 计数器是FPGA开发中最常用的电路&#xff0c;列如通讯中记录时钟个数&#xff0c;跑马灯中时间记录&#xff0c;存储器中地址的控制等等。本节给出向上计数器&#xff0c;上下计数器以及双向计数器案例。 内容 1. 向上计数器 2.向下计数器 3.向上向下计数…

迷你型洗衣机好用吗?高性价比的四款内衣洗衣机推荐

不得不说内衣洗衣机的发明解放了我们的双手&#xff0c;而我们从小到大就有这个意识&#xff0c;贴身衣物不可以和普通的衣服一起丢进去洗衣机一起&#xff0c;而内衣裤上不仅有肉眼看见的污渍还有手上根本无法消灭的细菌&#xff0c;但是有一款专门可以将衣物上的细菌杀除的内…

机器学习——自领域适应作业

任务 游戏里面的话有很多跟现实不一样的情况。 想办法让中间的特征更加的接近&#xff0c;让feat A适应feat B&#xff0c;产生相对正常的输出。 在有标签数据和没有数据的上面进行训练&#xff0c;并能预测绘画图像。 数据集 训练5000张总数&#xff0c;每类有500张测试100…

人工智能数据挖掘:发掘信息的新境界

导言 人工智能数据挖掘作为信息时代的利器&#xff0c;通过智能算法和大数据技术的结合&#xff0c;为企业、学术研究和社会决策提供了前所未有的洞察力。本文将深入探讨人工智能在数据挖掘领域的应用、技术挑战以及对未来的影响。 1. 人工智能数据挖掘的基本原理 数…

Python学习笔记(一)Anaconda开发环境介绍与搭建

本文介绍了Python学习中常用的开发环境Anaconda&#xff0c;以及如何搭建和使用Anaconda。Anaconda是一个集成了许多模块和包管理工具的软件集合&#xff0c;可以管理Python解释器、模块和虚拟环境。文章还比较了conda和pip这两个包管理工具的区别&#xff0c;并介绍了Anaconda…

Unity实现GoF23种设计模式

文章目录 Unity实现GoF23种设计模式概要一、创建型模式(Creational Patterns):二、结构型模式(Structural Patterns):三、行为型模式(Behavioral Patterns):Unity实现GoF23种设计模式概要 GoF所提出的23种设计模式主要基于以下面向对象设计原则: 对接口编程而不是对实…

Lambda表达式的简单理解

1. 初识lambda表达式 Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。 Lambda 表达式&#xff08;Lambda exp…

✺ch4——管理3D图形数据

目录 缓冲区和顶点属性统一变量顶点属性插值应用变换矩阵一个3D立方体示例渲染一个对象的多个副本——实例化在同一场景中渲染多个不同模型矩阵栈应对“Z冲突”伪影图元的其他选项性能优先的编程方法 使用 OpenGL 渲染 3D 图形通常需要将若干数据集发送给 OpenGL 着色器管线。举…

DS哈希查找—线性探测再散列

Description 定义哈希函数为H(key) key%11&#xff0c;输入表长&#xff08;大于、等于11&#xff09;。输入关键字集合&#xff0c;用线性探测再散列构建哈希表&#xff0c;并查找给定关键字。 –程序要求– 若使用C只能include一个头文件iostream&#xff1b;若使用C语言…

giee 添加公匙 流程记录

一、安装 百度网盘CSDN4文件夹下&#xff0c;或者官网下载&#xff1a;https://git-scm.com/downloads 二、生成密钥 1.右击打开git bash 2.$ ssh-keygen -t rsa -C “个人邮箱地址”&#xff0c;按3个回车&#xff0c;密码为空。 3.在C:\Users{windows用户名}.ssh目录下得到…