30. 串联所有单词的子串
时间:2019-09-14
本文章向大家介绍30. 串联所有单词的子串,主要包括30. 串联所有单词的子串使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
示例 1:
输入:
s = "barfoothefoobarman",
words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoor" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。
示例 2:
输入:
s = "wordgoodgoodgoodbestword",
words = ["word","good","best","word"]
输出:[]
/* 解题思路: 这道题让我们求串联所有单词的子串,就是说给定一个长字符串, 再给定几个长度相同的单词,让我们找出串联给定所有单词的子串的起始位置, 还是蛮有难度的一道题。假设 words 数组中有n个单词,每个单词的长度均为 len, 那么实际上这道题就让我们出所有长度为 n*len 的子串,使得其刚好是由 words 数组中的所有单词组成。 那么我们就需要经常判断s串中长度为 len 的子串是否是 words 中的单词,为了快速的判断,就要使用哈希表, 同时由于 words 数组可能有重复单词,所以就要用 HashMap 来建立所有的单词和其出现次数之间的映射, 即统计每个单词出现的次数。我们需要遍历s中所有长度为 n*len 的子串,当剩余子串的长度小于 n*len 时, 就不用再判断了。所以我们的i从0开始,到 (int)s.size() - n*len 结束就可以了,注意这里一定要将 s.size() 先转为整型数,再进行解法。一定要形成这样的习惯,一旦 size() 后面要减去数字时,先转为 int 型, 因为 size() 的返回值是无符号型,一旦减去一个比自己大的数字,则会出错。对于每个遍历到的长度为 n*len 的子串, 需要验证其是否刚好由 words 中所有的单词构成,检查方法就是每次取长度为 len 的子串,看其是否是 words 中的单词。 为了方便比较,我们建立另一个 HashMap,一旦取出的单词不在 words 中,直接 break 掉,否则就将其在新的 HashMap 中的映射值加1,还要检测若其映射值超过原 HashMap 中的映射值,也 break 掉,因为就算当前单词在 words 中, 但若其出现的次数超过 words 中的次数,还是不合题意的。在 for 循环外面,若j正好等于n, 说明我们检测的n个长度为 len 的子串都是 words 中的单词,并且刚好构成了 words, 则将当前位置i加入结果 res 即可 */ #include<iostream> #include<unordered_map> #include<vector> #include<string> using namespace std; class Solution { public: vector<int> fs(string s, vector<string>& words) { if (s.empty() || words.empty()) return{}; vector<int> res; int n = words.size(), len = words[0].size(); unordered_map<string, int> wordCnt;//unordered_map的迭代器是一个指针,指向这个元素,通过迭代器来取得它的值。 for (auto &word : words)//for(auto &a : arr)中“auto &a”就是变量名就和上一个for循环中的“int i”一样, //与for(int i = 0; i<sizeof(arr); i++)是一样的。 ++wordCnt[word]; for (int i = 0; i <= (int)s.size() - n * len; ++i) { unordered_map<string, int> strCnt; int j = 0; for (j = 0; j < n; ++j) { string t = s.substr(i + j * len, len); if (!wordCnt.count(t)) break; ++strCnt[t]; if (strCnt[t] > wordCnt[t]) break; } if (j == n) res.push_back(i); } return res; } }; int main(){ string s1; cin >> s1; string a[100]; int x; int i = 0; vector<string>vec; while (cin >> a[i]) { vec.push_back(a[i]); i++;//注意这里i++对输出结果的影响 x = cin.get(); if (x == '\n') break; } vector<int>ans = Solution().fs(s1, vec); for (int i = 0; i < ans.size(); i++) { cout << ans[i] << endl; } system("pause"); return 0; }
原文地址:https://www.cnblogs.com/277223178dudu/p/11519994.html
- Android系统线控和歌曲信息屏显的那点事
- 利用Spring中同名Bean相互覆盖的特性,定制平台的类内容。
- 关于java传参
- 浅析ButterKnife
- SQL Server常用语句
- pyecharts(一):Python可视化利器
- 如何在Python中保存ARIMA时间序列预测模型
- SVN+Apache域用户认证配置方法_Windows(转,重新排版,部分内容更新优化)
- sum(x) over( partition by y ORDER BY z ) 分析
- Android DataBinding 数据绑定
- Flask拾遗笔记之上下文
- switch.....case....使用最容易犯错的地方
- electron 构建跨平台桌面应用
- 两个关于字符串的经典例子
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- JDK 15已发布,你所要知道的都在这里!
- [Concent速成] (1) 定义和共享模块状态
- 利用JS代码批量自动取消抖音关注
- 开机报错/dev/vda1 contains a file system with errors,check forced.
- centos内核的删除或修改
- chkconfig学习笔记
- 3分钟短文:说说Laravel通用缓存Cache的使用技巧
- 【技术创作101训练营】想用代码改变世界?先用好Git和Github!
- 绘制散点图(克利夫兰系列)
- 绘制分组散点图(克里夫兰点图)
- ggplot2绘制玫瑰图
- 绘制极坐标系条形图
- 四步重新认识冗余机器人的控制器设计
- 人脸识别接入常见问题汇总
- TKE上关于postStart 和preStop使用