[理解leetcode解法]30. Substring with Concatenation of All Words找子串

30. Substring with Concatenation of All Words找子串

#难度:Difficulty: Hard

#题目:

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"]
(order does not matter).

You should return the indices: [0,9].


#题目中文意思:
给定你一个字符串s,和一词组(words),词组里面这些单词是相同长度的。在字符串s中找出“包含词组里面所有单词(顺序随机,且每个词语只出现一次)的子串在s中的位置”


#题解:

[理解leetcode解法]30. Substring with Concatenation of All Words找子串_第1张图片


class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> result;
        int word_length=words[0].size();                        //1
        int words_length=words.size();                          //2
        int s_len=s.length();                                            //3
       
        if(!s_len || words.empty()){
            return vector<int>();
        }
       
        map<string,int> all_words;                                //4
        map<string,int> cur_word;                                //5
       
        for(auto &i : words){                                          //6
            ++all_words[i];
        }
       
        for(int i=0;i<=(s_len - word_length*words_length);i++){       //7
            cur_word.clear();
            int j=0;
            for(j=0;j<words_length;j++){                                                //8
                string tmp=s.substr(i+j*word_length,word_length);       //9
                if(all_words.find(tmp)==all_words.end()){                      //10
                    break;
                }
                ++cur_word[tmp];                                                            //11
                if(cur_word[tmp]>all_words[tmp]){                                //12
                    break;
                }
            }
            if(j==words_length){                                      //13
                result.push_back(i);  
            }
        }
        return result;
    }
};




























#题解注释:(懒得逐个上传图片了 - -)

[理解leetcode解法]30. Substring with Concatenation of All Words找子串_第2张图片

[理解leetcode解法]30. Substring with Concatenation of All Words找子串_第3张图片


#附注

map的简略用法:
键值配对,通过键找值
例如本题中  map<string,int> all_words;
通过步骤//6
那么all_words["foo"]==1;

map的查找方式:
第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了
第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器


C++新特性:
特性一:auto的用法,不写了,比较容易理解,在关于C++板块有
特性二:

基于范围的for循环

在C++03中,要遍历一个list中的元素需要很多代码.其它语言实现支持"糖块句法",允许程序通过一个简单的"foreach"语句自动遍历list中的元素.其中之一就是Java语言, 它从5.0开始支持增强的for循环.
     C++11增加了一个类似的特性, for语句可以简单地遍历列表中的元素.

int my_array[5] = {1, 2, 3, 4, 5};
        // double the value of each element in my_array:for (int &x : my_array) 
        {
            x *= 2;
        }

  这种形式的for语句叫作"基于范围的for语句",它会遍历列表中的每一个元素.可以用在C风格数组,初始化列表和那些带有能返回迭代器的begin()和end()函数的类型上.所有提供了begin/end的标准容器都可以使用基于范围的for语句.


你可能感兴趣的:(LeetCode)