标签:子串 queue string int 30 单词 words LeetCode String
题目描述
难度 困难
给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。
示例 1:
输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。
示例 2:
输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
示例 3:
输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
输出:[6,9,12]
提示:
1 <= s.length <= 104
s 由小写英文字母组成
1 <= words.length <= 5000
1 <= words[i].length <= 30
words[i] 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
* 思路1:(行不通)
* 求出words可以组成的所有的不同的组合数,并存入字符串数组;
* String.indexof求得下标;
* 思路2:解答错误
* 游动串思路(扫描思路,每次移动1位)+2个HashMap+1个队列来实现
代码实现
扫描思路示意图
class Solution {
/**
* 游动串实体类
*/
class SwimmingEntity {
//下标
int position = -1;
//串值
String string = "";
public SwimmingEntity(int position, String string) {
this.position = position;
this.string = string;
}
}
/**
* 思路1:(行不通)
* 求出words可以组成的所有的不同的组合数,并存入字符串数组;
* String.indexof求得下标;
* <p>
* 思路2:
* 游动串思路+2个HashMap+1个队列来实现
* <p>
* 执行结果:解答错误
* 通过测试用例:115 / 176
* 输入:
* "wordgoodgoodgoodbestword"
* ["word","good","best","good"]
* 输出:
* []
* 预期结果:
* [8]
* 2021年 11月 10日 星期三 09:18:44 CST
* <p>
* 执行结果:解答错误
* 通过测试用例:122 / 176
* 输入:
* "ababababab"
* ["ababa","babab"]
* 输出:
* []
* 预期结果:
* [0]
* 2021年 11月 10日 星期三 11:45:00 CST
* <p>
*
* @param s
* @param words
* @return
*/
public List<Integer> findSubstring(String s, String[] words) {
char[] strChars = s.toCharArray();
int strLen = strChars.length;
int wordCounts = words.length;
int wordLen = words[0].length();//每组的单词长度是均等的
if (strLen > 104) return null;
if (wordCounts > 5000) return null;
//单词hashmap保存单词,k-单词,v-次数
HashMap<String, Integer> wordCombinationHashMap = new HashMap<String, Integer>(wordCounts);
//游动串hashmap保存单词,k-单词,v-次数
HashMap<String, Integer> swimmingBufferHashMap = new HashMap<String, Integer>(wordCounts);
for (int i = 0; i < wordCounts; i++) {
String currentKey = words[i];
if (wordCombinationHashMap.containsKey(currentKey)) {
wordCombinationHashMap.put(currentKey, wordCombinationHashMap.get(currentKey) + 1);
} else {
wordCombinationHashMap.put(currentKey, 1);
}
}
//保存下标
List<Integer> positonList = new ArrayList<Integer>();
//队列(个数=wordCounts)
Queue<SwimmingEntity> queue = new LinkedList<>();
//StringBuilder
StringBuilder swimmingBuilder = new StringBuilder();
//外围总游动次数
int swimmingCounts = strLen - wordLen + 1;
for (int swimmingIndex = 0; swimmingIndex < swimmingCounts; swimmingIndex++) {
//游动串
for (int i = 0; i < wordLen; i++) swimmingBuilder.append(strChars[swimmingIndex + i]);
//将符合单词条件的游动串对象加入队列
if (wordCombinationHashMap.containsKey(swimmingBuilder.toString())) {
SwimmingEntity swimmingEntity = new SwimmingEntity(swimmingIndex, swimmingBuilder.toString());
((LinkedList<SwimmingEntity>) queue).add(swimmingEntity);
//#0检查-每当wordCounts个单词游串的时候做1次检查
if (queue.size() == wordCounts) {
boolean check = true;//默认值
int firstposition = ((LinkedList<SwimmingEntity>) queue).get(0).position;
//检测是否符合目标组合串
for (int queueIndex = 0; queueIndex < queue.size(); queueIndex++) {
SwimmingEntity tmpEntity = ((LinkedList<SwimmingEntity>) queue).get(queueIndex);
//#1连续性判断(下标的方式)
if (!(tmpEntity.position == firstposition + queueIndex * wordLen)) {
check = false;
break;
}
//#2重复性检测判断(可以重复,重复性检测),但出现的次数不大于单个单词的最大重复次数
if (swimmingBufferHashMap.containsKey(tmpEntity.string)) {
//#2.1获取当前单词在队列中出现的重复次数
int currentWordrepeat = 0;
String currentWord = tmpEntity.string;
for (int repeatIndex = 0; repeatIndex < queue.size(); repeatIndex++) {
if (currentWord.equals(((LinkedList<SwimmingEntity>) queue).get(repeatIndex).string)) {
currentWordrepeat++;
}
}
//#2.2标记失败,结束循环
if (currentWordrepeat != wordCombinationHashMap.get(tmpEntity.string)) {
check = false;
break;
}
}
swimmingBufferHashMap.put(tmpEntity.string, tmpEntity.position);
}
//清除swimmingBufferHashMap
swimmingBufferHashMap.clear();
//检测是否符合目标串
if (check) {
//#3保存下标,并且将首个游动串对象移出队列
positonList.add(queue.poll().position);
} else {
queue.poll();
}
}
}
//清除游动串
swimmingBuilder.delete(0, wordLen);
}
return positonList;
}
}
执行结果:解答错误
通过测试用例:122 / 176
输入:
"ababababab"
["ababa","babab"]
输出:
[]
预期结果:
[0]
头大,暂未实现,记录与总结,2021年 11月 10日 星期三 12:09:38 CST。
标签:子串,queue,string,int,30,单词,words,LeetCode,String 来源: https://blog.csdn.net/u014132947/article/details/121240548
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。