• 30. Substring with Concatenation of All Words找出串联所有词的子串


    题目:https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/

    You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

    For example, given:
    s: "barfoothefoobarman"
    words: ["foo", "bar"]

    You should return the indices: [0,9].
    (order does not matter).

    找到索引,连续能匹配所有子串,(各子串匹配的顺序不考虑);

    比如要匹配的子串集["foo", "bar"],那么母串是"barfoothefoobarman"时,返回[0,9]。因为index = 0时有“barfoo”,index = 9时,有“foobar

    解决:

    1、用到map结构(有点像hash)的counts,用来存放要匹配的子串s还有要匹配它的次数:counts( s ) = 要匹配的次数。

      比如counts("bar") = 1,counts("foo") = 1;

    2、从母串的第一位开始匹配(匹配成功或失败,第二次都从第二位开始,第三次从第三位。。即每次向后挪一位进行匹配):{

        取长度len(每个word的长度)的字符串word{

          看这个word是否在要匹配的counts中包含?

          如果包含,进行seen(word)++,并判断seen(word)是否大于counts(word)。

          如果不包含或子串出现次数大于要匹配的次数,break;

        }接着紧挨着再取长度为len。。

      }

    class Solution {
    public:
        vector<int> findSubstring(string s, vector<string>& words) {
            unordered_map<string, int> counts;  //string代表子串,int代表要匹配的word的个数
            for (string word : words)
                counts[word]++; //某个word要匹配的个数
            int n = s.length(), num = words.size(), len = words[0].length(); //n:母串长度,num:要匹配几个word,len:字串长度(每个word的长度相等)
            vector<int> indexes;   //放入匹配的index
            for (int i = 0; i < n - num * len + 1; i++) {  //从母串的第一个元素开始,每次挪一位匹配
                unordered_map<string, int> seen;     //seen记录word被包含的次数(不得大于要匹配的次数:counts中记录)
                int j = 0;
                for (; j < num; j++) {(
                    string word = s.substr(i + j * len, len);   //每次从母串截取长度len长度的字符串word,看是否是要匹配的word
                    if (counts.find(word) != counts.end()) {  //word是否在counts中找到
                        seen[word]++;  //
                        if (seen[word] > counts[word])  //匹配多余时要break(比如只要匹配一个abb,但是总共出现了两个abb就不对了)
                            break;
                    } 
                    else break;
                }
                if (j == num) indexes.push_back(i);  //每个word都匹配好,
            }
            return indexes;
        }
    };

    最笨的方法了。其他好方法可参见:https://leetcode.com/problems/substring-with-concatenation-of-all-words/discuss/

  • 相关阅读:
    redis 日常使用
    centos7新装mysql 5.7
    spring 的常用功能
    软件安装教程
    每日成长17年1月
    ubuntu下不用拔盘就可以重新识别usb设备
    使用Linux遇到的一些问题和解决方案
    在XEN上启动guest时loopback设备不足
    使用virtualenv搭建python虚拟开发环境
    Linux局域网登陆响应时间过长
  • 原文地址:https://www.cnblogs.com/hozhangel/p/7840619.html
Copyright © 2020-2023  润新知