leetcode - 串联所有单词的子串 - 最小覆盖子串 - x 的平方根

I30. 串联所有单词的子串 - 力扣(LeetCode)

给定一个字符串 s 和一个字符串数组 words words 中所有字符串 长度相同

 s 中的 串联子串 是指一个包含  words 中所有字符串以任意顺序排列连接起来的子串。

  • 例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd""cdabef", "cdefab""efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。

返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。

示例 1:

输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。
子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。
输出顺序无关紧要。返回 [9,0] 也是可以的。
示例 2:

输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以我们返回一个空数组。
示例 3:

输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
输出:[6,9,12]
解释:因为 words.length == 3 并且 words[i].length == 3,所以串联子串的长度必须为 9。
子串 "foobarthe" 开始位置是 6。它是 words 中以 ["foo","bar","the"] 顺序排列的连接。
子串 "barthefoo" 开始位置是 9。它是 words 中以 ["bar","the","foo"] 顺序排列的连接。
子串 "thefoobar" 开始位置是 12。它是 words 中以 ["the","foo","bar"] 顺序排列的连接。
 

这个题目就是 找到字符串中所有字母异位词 这个题目的升级版,具体可以看一下博客:
leetcode 刷题 - 最大连续1的个数 - 将 x 减到 0 的最小操作数 - 水果成篮 - 找到字符串中所有字母异位词-CSDN博客

其实就是把 找到字符串中所有字母异位词 这个题目 当中的 字符换成了 字符串。

所以,其实基本思想还是和 找到字符串中所有字母异位词 这个题目 一样的,只不过,hash表不能再用 数组来模拟了,要使用 hash容器。

而且,left 和 right 迭代器方式也不再是一步一步的向后移动了,而是一个子串的一个子串的移动。

而且,在这个题目当中,滑动窗口的 起始位置可能不是 从数组的最开始位置开始的,可能从 第二,第三··· 都有可能,但是,如果超过了 words 数组当中一个子串的 大小,那么后续就会是重复的。

所以,我们的滑动窗口,不能像 之前题目当中,只滑动一遍数组,而是要滑动 len 次数组(其实位置依次往后移一个字符),len就是words 当中子串的字符个数。

完整代码:

class Solution
{
public:
    vector<int> findSubstring(string s, vector<string>& words)
    {
        vector<int> ret;
        unordered_map<string, int> hash1; // 保存 words ⾥⾯所有单词的频次
        for (auto& s : words) hash1[s]++;
        int len = words[0].size(), m = words.size();
        for (int i = 0; i < len; i++) // 执⾏ len 次
        {
            unordered_map<string, int> hash2; // 维护窗⼝内单词的频次
            for (int left = i, right = i, count = 0; right + len <= s.size();
                right += len)
            {
                // 进窗⼝ + 维护 count
                string in = s.substr(right, len);
                hash2[in]++;
                if (hash1.count(in) && hash2[in] <= hash1[in]) count++;
                // 判断
                if (right - left + 1 > len * m)
                {
                    // 出窗⼝ + 维护 count
                    string out = s.substr(left, len);
                    if (hash1.count(out) && hash2[out] <= hash1[out]) count--;
                    hash2[out]--;
                    left += len;
                }
                // 更新结果
                if (count == m) ret.push_back(left);
            }
        }
        return ret;
    }
};

I76. 最小覆盖子串 - 力扣(LeetCode)

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。
示例 2:

输入:s = "a", t = "a"
输出:"a"
解释:整个字符串 s 是最小覆盖子串。
示例 3:

输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

 其实这个题目,和上述所说的两个题目是类似的,只不过在判断条件当中,上两个题目是 当 窗口不合法,然后出窗口,但是这个题目是 窗口合法,就更新结果,然后出窗口。

同样的,使用 left 和 right 两个指针,从开始来进行遍历,用两个 hash 表分别存储 s 和 t 两个字符串当中 各个 字符的数量。

right 依次向后走,把遍历的 每一个 s 当中的字符,记录在 自己 hash 表当中,也就是 hash 表当中计数器++。(进窗口)

当 right 向后迭代,窗口合法,就更新结果,然后 循环 left++,向后迭代,同样的,left 遍历的过的字符 来 出窗口,在 hash 的计数器--。一直left++ 到 窗口不合法。

判断两个 s 相对于 t 当中的在  t 当中在 s 当中存在的字符 的个数,要大于等于 t 当中对应字符的 数量,才称之为 s 当中的这个字符是 有效字符。

当有效字符 等于 t 当中字符种类数量,才认为 当前窗口合法。

判断 两个 hash 表 是否相等,可以使用上述 有效字符 的方式进行优化,具体就是:

我们可以用一个 count 记录 有效字符。什么是 有效字符呢?就是在我们所寻找的子串当中,有多少 种类 的字符,是和 目标字符是 一样的。如果有一个 种类 是一样的,count++。

所以,在 存储我们找出的子串当中 各个字符出现次数 的 hash 表当中,依旧按照 滑动窗口 当中的逻辑,进行 计数,只不过,如果是  和 目标字符 hash 当中有重复的,也就是当前的 计数器++ 的是 有效字符,那么就 count++。

当 count == 目标子串.size() 之时,采取更新结果,否则,当前找出的 这个子串 就不满足条件。
 

完整代码:

class Solution {
public:
    string minWindow(string s, string t) {
        char hash_s[128] = {0}; // 用于存储 s 字符串当中 各个字符出现的次数
        char hash_t[128] = {0}; // 用于存储 t 字符串当中 各个字符出现的次数

    //记录t字符种类数量 当前最小长度       当前最小程度的子串在 s 当中的起始位置
        int kinds = 0, minlen = INT_MAX, begin = -1;
        for(auto& e : t) if(hash_t[e]++ == 0) kinds++;

        for(int left = 0, right = 0, count = 0; right < s.size();right++)
        {
            char right_str = s[right]; // 取出当前 right 指向的字符
            hash_s[right_str]++;       // 哈希表计数器++
            if(hash_s[right_str] == hash_t[right_str]) count++; // 如果在上述计数器++之后
                                                                // 满足条件,count++
            // 如果当前 s 当中的有效字符 和 t 当中的 字符种类相等
            // 说明当前窗口 合法
            // 更新结果,循环一直 left++, 直到 窗口不再合法
            while(count == kinds)
            {
                if(right - left + 1 < minlen)
                {
                    minlen = right - left + 1;
                    begin = left;
                }
                
                char left_str = s[left++];// 取出当前 left 指向的字符,然后 left++
                if(hash_s[left_str] == hash_t[left_str]) count--; //如果left指向字符出窗口之后
                                                                  // 当前字符个数不在和t相比是
                                                                  // 大于等于 t 对应字符数量
                hash_s[left_str]--;
            }
        }

        if(begin == -1) return "";
        else return s.substr(begin, minlen); // 如果有结果,就切割字符串,然后返回
    }
};

I69. x 的平方根 - 力扣(LeetCode)

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

示例 1:

输入:x = 4
输出:2
示例 2:

输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
 

 完整代码:
 

class Solution {
public:
    int mySqrt(int x) {
        if(x < 1) return 0; // 处理边界情况

        int left = 1, right = x;
        while(left < right)
        {
            // 找到 left 和 right 的中间数值
            long long mid = left +  (right - left + 1) / 2; //  long long防止 mid * mid 溢出
            if(mid * mid <= x) left = mid;  // 刷新 左右区间
            else right = mid -1;
        }
        return left;

    }
};

I【模板】前缀和_牛客题霸_牛客网 (nowcoder.com)

描述

给你一个 n 行 m 列的矩阵 A ,下标从1开始。

接下来有 q 次查询,每次查询输入 4 个参数 x1 , y1 , x2 , y2

请输出以 (x1, y1) 为左上角 , (x2,y2) 为右下角的子矩阵的和,

输入描述:

第一行包含三个整数n,m,q.

接下来n行,每行m个整数,代表矩阵的元素

接下来q行,每行4个整数x1, y1, x2, y2,分别代表这次查询的参数

 

输出描述:

输出q行,每行表示查询结果。

示例1
输入:
3 4 3
1 2 3 4
3 2 1 0
1 5 7 8
1 1 2 2
1 1 3 3
1 2 3 4
复制
输出:
8
25
32

使用前缀和 -> 快速求出数组当中某一个连续区间的和

先要预处理出来一个前缀和数组(dp数组),dp[i] 元素存储的是 原数组当中从起始位置,到 i 位置 这个连续区间当中 元素之和

所以,在以后 寻找的过程当中,只需要以 下标对应 dp 当中存储的和,相减即可。比如 :给定区间 [1, 3] ,那么这个区间当中的和就等于 dp[3] - dp[1]

完整代码:

#include <iostream>
#include<vector>
using namespace std;

int main() {
    int n,q;
    cin >> n >> q;
    vector<int> arr(n + 1);
    vector<long long> dp(n + 1, 0); // long long 防止溢出

    for(int i = 1;i <= n;i++) cin >> arr[i];
    for(int i = 1;i <= n;i++) dp[i] = dp[i - 1] + arr[i];

    int l , r;
    while(q--)
    {
        cin >> l >> r;
        cout << dp[r] - dp[l - 1] << endl;
    }

    return 0;
}

I【模板】二维前缀和_牛客题霸_牛客网 (nowcoder.com)

描述

给你一个 n 行 m 列的矩阵 A ,下标从1开始。

接下来有 q 次查询,每次查询输入 4 个参数 x1 , y1 , x2 , y2

请输出以 (x1, y1) 为左上角 , (x2,y2) 为右下角的子矩阵的和,

输入描述:

第一行包含三个整数n,m,q.

接下来n行,每行m个整数,代表矩阵的元素

接下来q行,每行4个整数x1, y1, x2, y2,分别代表这次查询的参数

输出描述:

输出q行,每行表示查询结果。

示例1
输入:
3 4 3
1 2 3 4
3 2 1 0
1 5 7 8
1 1 2 2
1 1 3 3
1 2 3 4
复制
输出:
8
25
32

和上述一样,使用 前缀和 来解决上述的问题。

dp[i][j] 表示,从 [1,1] 位置到 [i,j] 位置,这段区间当中所有的元素的和。

但是,dp 这个二维数组不好求,如果我们直接遍历来一个一个求的话,时间复杂度很高。

所以,其实 dp[i][j] 其实就是 A + B + C + D,这四个之和。单独求 A 其实很好求,找到 i -1 和 j -1 ,位置,就可以求出 dp[i-1][j-1] 就是 A 的面积。

因为单独求 C 和 B 不好求。

 A + B + C + D = (A + B) + (A + C) + D - A

 上述 (A + B) 和 (A + C) 就可以求出。

 所以 : dp[ i ][ j ] = dp[ i-1 ][ j ] + dp[ i ][ j-1 ] + arr[ i ][ j ] +dp[ i-1 ][ j-1 ]  

所以:

完整代码:

#include <iostream>
#include<vector>
using namespace std;

int main() {
    int n = 0, m = 0, q = 0;
    cin >> n >> m >> q;
    vector<vector<int>> arr(n + 1, vector<int>(m + 1));
    for(int i = 1; i <= n; i++)
        for(int j = 1; i <= m ;j++)
            cin >> arr[i][j];

    vector<vector<long long>> dp(n + 1, vector<long long>(m + 1));
    for(int i = 1; i <= n; i++)
        for(int j = 1; i <= m ;j++)
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + arr[i][j] - dp[i - 1][j - 1];

    int x1 , y1 , x2 , y2;
    while(q--)
    {
        cin >> x1 >> y1 >> x2 >> y2;
        cout << dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1] << endl;
    }

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何成为自信出色的演讲者?10条实用技巧助你登台亮相!

成为自信出色的演讲者需要长期练习和学习。以下是我总结的10条实用技巧&#xff1a; 了解你的观众 一个成功的演讲需要考虑观众的背景和需要。你需要了解他们的行业、兴趣和问题。这样可以帮助你调整内容和表达方式&#xff0c;让观众感兴趣并获得价值。你也可以事先收集一些…

PyCharm 远程连接服务器并使用服务器的 Jupyter 环境

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

架构师修炼之道

相信大家都对未来的职业发展有着憧憬和规划&#xff0c;要做架构师、要做技术总监、要做CTO。对于如何实现自己的职业规划也都信心满满&#xff0c;努力工作、好好学习、不断提升自己。 相信成为一名优秀的架构师是很多程序员的目标&#xff0c;架构师的工作包罗万象&#xff…

【星海出品】云存储 ceph

https://ceph.com/en/ ceph组件介绍 Monitor 一个Ceph集群需要多个Monitor组成的小集群&#xff0c;它们通过Paxos同步数据&#xff0c;用来保存OSD的元数据。 OSD OSD全称Object Storage Device&#xff0c;也就是负责响应客户端请求返回具体数据的进程。一个Ceph集群一般都有…

C#winform门诊医生系统+sqlserver

C#winform门诊医生系统sqlserver说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a;基于C#winform架构和sql server数据库 功能模块&#xff1a; 个人中心&#xff1a;修改个人信息、打开照片并进行修改 预约挂号&#xff1a;二级…

那些年我们追过的 内部类

目录 1. 什么是内部类&#xff1f; 2. 内部类的分类 3. 内部类 3.1 实例内部类 3.2 静态内部类 4. 局部内部类 5. 匿名内部类 6.对象的打印 “不积跬步无以至千里&#xff0c;不积小流无以成江海。”每天坚持学习&#xff0c;哪怕是一点点&#xff01;&#xff01;&a…

SQL题

[极客大挑战 2019]EasySQL 进行简单的尝试&#xff0c;就知道是单引号的字符型注入 万能密码进行一个简单的尝试 结果就出来了 还是要了解一下原理 输入的是1&#xff0c;形成的sql语句是错误的SELECT*FROM table_name WHERE username1and password123; 第一个单引号和第二个…

【2023最全教程】python+appium自动化测试元素定位(建议收藏)

关于app自动化测试&#xff0c;元素定位工具有三个&#xff1a; appium自带的Appium Inspector工具 Android ADT原生的工具 python版uiautomator2中的weditor 由于我常用的是前两个&#xff0c;所以下面只介绍前面两种元素定位工具&#xff08;以下内容中均以微博为例子&am…

centos的root密码忘记或失效的解决办法

目录 前言1 单机维护模式2 利用具有管理员权限的用户切换到root用户3 救援模式 前言 在Linux系统中&#xff0c;root用户是最高权限的用户&#xff0c;可以执行任何命令和操作。但是&#xff0c;如果我们忘记了root用户的密码&#xff0c;或者需要修改root用户的密码&#xff…

Vue-Pinia

目录 Pinia状态管理库 使用步骤 1、安装Pinia 2、在vue应用实例中使用pinia 3、在src/stores/token.js中定义stores 4、在组件中使用store axios请求拦截器 代码实现 Pinia状态管理库 Pinia是Vue的专属状态管理库&#xff0c;它允许你跨组件或页面共享状态 一般在登录时…

Java 各种工具类的使用方法

1. 属性拷贝 属性名词和类型相同才能拷贝 import org.springframework.beans.BeanUtils; BeanUtils.copyProperties(dto,wmNews); //dto, wmNews 是两个实体类 dto为源对象&#xff0c;wmNews为目标对象2. list集合转换为string类型 import org.apache.commons.lang3.String…

将Python程序(.py)转换为Windows可执行文件(.exe)

python开发者向普通windows用户分享程序,要给程序加图形化的界面(传送门:这可能是最好玩的python GUI入门实例! http://www.jianshu.com/p/8abcf73adba3),并要将软件打包为可执行文件(.exe结尾),那如何将.py转为.exe ? 将.py转为.exe 第一步:安装pyinstaller(临时调用了国内豆…

atoi函数的模拟实现

函数原型&#xff1a;int atoi (const char * str); 作用&#xff1a;将字符串转换为整数 注意事项&#xff1a; 1、会忽略字符串前的空白字符&#xff0c;并从第一个非空白字符开始解析整数&#xff0c;直到遇到非数字字符为止 具体代码如下&#xff1a; #include <s…

sscanf提取相应字符到数组

代码如下 #include<stdio.h> #include<string.h>int main(int argc, char const *argv[]) {char buf[128] {0};int m1 0, m2 0;int s1 0, s2 0;char lrc[128] "";sscanf("[02:16.33][04:11.44]我想大声宣布对你恋恋不舍","[%*1d%d…

gitLab server version 13.12.1 is not supported

拉代码的时候&#xff0c;报的这个错&#xff0c;实际上就是因为gitLab 版本太低了&#xff0c;这里不准备升级版本&#xff0c;打算继续使用账号密码来拉取代码 在idea已经安装的插件中&#xff0c;去掉gitlab插件&#xff0c;如下&#xff1a; 之后再拉取代码&#xff0c;就…

五分钟学会搭建悟空CRM内网穿透,实现公网访问企业内网,提升工作效率!

文章目录 前言1. 无需公网IP&#xff0c;使用cpolar实现悟空CRM远程访问2. 通过公网来访问公司内网悟空CRM3. 设置固定连接公网地址 前言 悟空CRM是一款开源的客户关系管理系统&#xff0c;以"客户关系一对一理论"为基础&#xff0c;通过对企业业务流程的重组来整合…

【MATLAB】史上最全的7种回归预测算法全家桶

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 大家吃一顿火锅的价格便可以拥有9种时序预测算法&#xff0c;绝对不亏&#xff0c;知识付费是现今时代的趋势&#xff0c;而且都是我精心制作的教程&#xff0c;有问题可随时反馈~也可单独获取某一算法的代码&#xff08…

《C++避坑神器·十九》C++多线程使用,啥也不懂看它就对了

C11后有了标准的线程库&#xff1a; #include <thread>并发 是指多个线程任务在同一个CPU上快速地轮换执行&#xff0c;由于切换的速度非常快&#xff0c;给人的感觉就是这些线程任务是在同时进行的&#xff0c;但其实并发只是一种逻辑上的同时进行&#xff1b; 并行 是…

GPTS全网刷屏!定制增长速度指数增长

还记的上周OpenAI刚刚举行完开发者大会&#xff0c;在大会上主要公布了三个事情&#xff1a; 新版本的GPT-4 Turbo&#xff1a;更强大、更便宜且支持128K新的助手API&#xff1a;让开发者更轻松地基于GPT构建辅助AI应用平台中新的多模态功能&#xff1a;包括视觉、图像创作&am…