Substring with Concatenation of All Words@LeetCode

区星
• 阅读 6846

Substring with Concatenation of All Words

比较复杂的一题,首先是要明确用滑块的概念来解决,始终保持L集合中的字符串在滑块中都只出现了一次,当然设置一个总计数count,当cout等于L集合长度时,即使找了一段符合要求的字符串。

需要用到的内存空间:

  • 两张哈希表,一张保存L集合中的单词,一张用来保存当前滑块中的单词,key为单词,value为出现次数
  • cout计数,保存当前滑块中的单词总数
  • left标记,记录滑块左起点

实现的步骤:

  1. 遍历一遍单词数组L集合,构造总单词表
  2. 以单词长度为步长,遍历目标字符串,如果当前单词在总单词表内,则进入步骤3;反之,则清空当前滑块单词表,将cout置零,将left移动到下一位置
  3. 当前滑块档次表中的相应单词计数加1,检查该单词的计数是否小于等于总单词表中该单词的总数,如果是,则将count计数加1,进入步骤5;反之,进入步骤4
  4. 根据左起点left收缩滑块,直到收缩到与当前单词相同的字符串片段,将其剔除之后,滑块的收缩工作完成
  5. 如果当前count计数等于单词集合长度,记录下left左起点的位置后,将left右移,当前滑块中相应单词计数减1,总计数减1,继续循环

这里解释下步骤4中的收缩滑块,这是因为当前滑块中有单词的出现次数超过了额定的出现次数,那么就是需要收缩滑块来剔除这个单词,相当于是从滑块的左起点开始寻找该单词,找到之后,将该单词的右端点作为滑块新的左起点,这样就保证了滑块中所有单词都是小于等于额定出现次数,这样也保证了count计数的有效性。

遇到总单词表中不存在的单词的情况,在步骤2中已经说明,清空当前数据之后继续循环,也就是保证了滑块中是不会出现不存在单词表中的单词的。

最后,考虑最外圈循环,如果是从0开始作为滑块的初始起点,那么其实并没有遍历字符串中的所有可能子串,因为步长是单词长度,所以移动滑块的时候会跨过很多可能子串,所以要在外圈再加一层循环,这个循环的作用就是移动滑块的初始起点,所以循环次数就是单词的长度。

实现代码:

javapublic class Solution {
    public List<Integer> findSubstring(String S, String[] L) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        if (S == null || S.length() == 0 || L == null || L.length == 0)
            return result;
        int strLen = S.length();
        int wordLen = L[0].length();
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        for (int i = 0; i < L.length; i++) {
            if (map.containsKey(L[i])) {
                map.put(L[i], map.get(L[i]) + 1);
            } else {
                map.put(L[i], 1);
            }
        }
        for (int i = 0; i < wordLen; i++) {
            HashMap<String, Integer> curMap = new HashMap<String, Integer>();
            int count = 0, left = i;
            for (int j = i; j <= strLen - wordLen; j += wordLen) {
                String curStr = S.substring(j, j + wordLen);
                if (map.containsKey(curStr)) {
                    if (curMap.containsKey(curStr)) {
                        curMap.put(curStr, curMap.get(curStr) + 1);
                    } else {
                        curMap.put(curStr, 1);
                    }
                    if (curMap.get(curStr) <= map.get(curStr)) {
                        count++;
                    } else {
                        while (true) {
                            String tmp = S.substring(left, left + wordLen);
                            curMap.put(tmp, curMap.get(tmp) - 1);
                            left += wordLen;
                            if (curStr.equals(tmp)) {
                                break;
                            } else {
                                count--;
                            }
                        }
                    }
                    if (count == L.length) {
                        result.add(left);
                        String tmp = S.substring(left, left + wordLen);
                        curMap.put(tmp, curMap.get(tmp) - 1);
                        left += wordLen;
                        count--;
                    }
                } else {
                    curMap.clear();
                    count = 0;
                    left = j + wordLen;
                }
            }
        }
        return result;
    }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Stella981 Stella981
3年前
LeetCode——295. Find Median from Data Stream
一.题目链接:  https://leetcode.com/problems/findmedianfromdatastream(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fleetcode.com%2Fproblems%2Ffindmedianfromdatast
Stella981 Stella981
3年前
Postman 使用方法详细介绍
1,下载安装:https://www.getpostman.com/apps2,打开Postman,如图所示:!(https://oscimg.oschina.net/oscnet/00f434cd831f2f74fea6f6d7b86bc46a751.png)3,创建一个接口项目!(https://oscimg.oschina.
Stella981 Stella981
3年前
LeetCode 1192. Critical Connections in a Network
原题链接在这里:https://leetcode.com/problems/criticalconnectionsinanetwork/(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fleetcode.com%2Fproblems%2Fcriticalconnections
Stella981 Stella981
3年前
558. Quad Tree Intersection
https://leetcode.com/problems/quadtreeintersection/description/我觉得是用意挺好的一题目。求两个四叉树的逻辑union,可惜测试用例里面居然包含对题目外因素的检查(那个id)懒得弄了。思路其实挺简单,但是很容易忽略一个edgecase,就是当所有children的value都一致
Stella981 Stella981
3年前
851. Loud and Rich —— weekly contest 87
851\.LoudandRich题目链接:https://leetcode.com/problems/loudandrich/description/(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fleetcode.com%2Fpr
Stella981 Stella981
3年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Stella981 Stella981
3年前
925. Long Pressed Name
题目链接:https://leetcode.com/problems/longpressedname/description/(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fleetcode.com%2Fproblems%2Flongpressedname%2Fdescript
Stella981 Stella981
3年前
Leetcode——Substring with Concatenation of All Word
Youaregivenastring, s,andalistofwords, words,thatareallofthesamelength.Findallstartingindicesofsubstring(s)in s thatisaconcatenationofeachwordin words
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
区星
区星
Lv1
远书归梦两悠悠,只有空床敌素秋。
文章
4
粉丝
0
获赞
0