[LeetCode-JAVA] Substring with Concatenation of All Words

题目:

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 wordsexactly once and without any intervening characters.

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

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

题意:题意很重要,开始理解错了,以为要求的是words中每个单词出现的index,真正的题意是,words中每一个单词都出现一次,并且中间不夹杂着其他的单词,即word中所有字符串组成的所有可能在s中出现的index。

思路:建立一个map来维护words的内容,key为words的string,value为对应的数量。 由于words的单词长度相同,因此每次查找的窗口大小一致,为words所有单词的总长度,不用判断边界条件。在判断过程中,建立一个临时的map,来与初始的map进行比较,符合的时候,向list中加入此时的index

代码:

public class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> list = new ArrayList<Integer>();
        if(s == null || s.length() == 0 || words.length == 0)
            return list;

        int wordCount = words.length;
        int wordlen = words[0].length();
        int len = wordlen * wordCount;  //总长度

        Map<String, Integer> map = new HashMap<String, Integer>();
        Map<String, Integer> cur = new HashMap<String, Integer>();

        for(int i = 0 ; i < wordCount ; i++){
            if(!map.containsKey(words[i]))
                map.put(words[i], 1);
            else
                map.put(words[i], map.get(words[i])+1);
        }
        boolean flag = true; //标志位
        for(int i = 0 ; i < s.length() - len + 1 ; i++){
            cur.clear(); //循环开始的时候清空上一次的操作
            flag = true;
            for(int j = 0 ; j < wordCount ; j++){
                String temp = s.substring(i + j*wordlen, i + wordlen*(j+1)); //每一个窗口
                if(!map.containsKey(temp)){
                    flag = false;
                    break;
                }

                if(!cur.containsKey(temp))
                    cur.put(temp, 1);
                else
                    cur.put(temp, cur.get(temp)+1);

                if(cur.get(temp) > map.get(temp)){
                    flag = false;
                    break;
                }
            }
            if(flag) // 如果不是意外break 则内容相符
                list.add(i);
        }
        return list;
    }
}

上面的是自己的思路,不是最快速的,大概是700ms 下面将内外循环换一下 速度提升了一倍 300ms

代码:

public class Solution {
    public static ArrayList<Integer> findSubstring(String S, String[] L) {
         ArrayList<Integer> res = new ArrayList<Integer>();
         if(S==null||L==null||S.length()==0||L.length==0)
            return res;
         int wordLen = L[0].length();//same length for each word in dictionary

         //put given dictionary into hashmap with each word‘s count
         HashMap<String, Integer> dict = new HashMap<String, Integer>();
         for(String word: L){
             if(!dict.containsKey(word))
                dict.put(word, 1);
             else
                dict.put(word, dict.get(word) + 1);
         }

         for(int i = 0; i < wordLen; i++){
             int count = 0;
             int index = i;//index of each startpoint
             HashMap<String, Integer> curdict = new HashMap<String, Integer>();
             //till the first letter of last word
             for(int j = i; j <= S.length() - wordLen; j += wordLen){
                 String curWord = S.substring(j, j + wordLen);
                 //check each word to tell if it existes in give dictionary
                 if(!dict.containsKey(curWord)){
                     curdict.clear();
                     count = 0;
                     index = j + wordLen;
                 }else{
                     //form current dictionary
                     if(!curdict.containsKey(curWord))
                        curdict.put(curWord, 1);
                     else
                        curdict.put(curWord, curdict.get(curWord) + 1);

                     //count for current found word and check if it exceed given word count
                     if(curdict.get(curWord) <= dict.get(curWord)){
                         count++;
                     }else{
                         while(curdict.get(curWord) > dict.get(curWord)){
                            String temp = S.substring(index, index + wordLen);
                            curdict.put(temp, curdict.get(temp)-1);
                            if(curdict.get(temp)<dict.get(temp)){
                                count--;
                            }
                            index = index + wordLen;
                        }
                     }

                     //put into res and move index point to nextword
                     //and update current dictionary as well as count num
                     if(count == L.length){
                         res.add(index);
                         String temp = S.substring(index, index + wordLen);
                         curdict.put(temp, curdict.get(temp)-1);
                         index = index + wordLen;
                         count--;
                     }
                 }
             }//end for j
         }//end for i
          return res;
        }
}

参考链接:http://www.cnblogs.com/springfor/p/3872516.html

时间: 2024-10-10 07:40:20

[LeetCode-JAVA] Substring with Concatenation of All Words的相关文章

[LeetCode] 030. Substring with Concatenation of All Words (Hard) (C++/Java)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 030. Substring with Concatenation of All Words (Hard) 链接: 题目:https://oj.leetcode.com/problems/substring-with-concatenation-of-all-words/ 代码(github):https://gi

[LeetCode] 30. Substring with Concatenation of All Words 解题思路 - Java

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 wordsexactly once and without any intervening characters. For example, give

leetCode 30.Substring with Concatenation of All Words (words中全部子串相连) 解题思路和方法

Substring with Concatenation of All Words 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 an

leetCode 30.Substring with Concatenation of All Words (words中所有子串相连) 解题思路和方法

Substring with Concatenation of All Words 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 an

【leetcode】Substring with Concatenation of All Words

Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any interv

LeetCode 030 Substring with Concatenation of All Words

题目要求:Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any i

leetcode 之 Substring with Concatenation of All Words

Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any interv

LeetCode 30 Substring with Concatenation of All Words (C,C++,Java,Python)

Problem: 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 wordsexactly once and without any intervening characters. For exam

Java [leetcode 30]Substring with Concatenation of All Words

题目描述: 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 exampl

LeetCode 30 Substring with Concatenation of All Words(确定包含所有子串的起始下标)

题目链接: https://leetcode.com/problems/substring-with-concatenation-of-all-words/?tab=Description 在字符串s中找到包含字符串数组words所有子串连续组合的起始下标(words中的子串排列顺序前后不计但是需要相连在s中不能存在其他字符) 参考代码 : package leetcode_50; import java.util.ArrayList; import java.util.Arrays; impo