Substring with Concatenation of All Words-Leetcode

来源:互联网 发布:淘宝网十字绣鞋垫 编辑:程序博客网 时间:2024/06/05 14:20

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).


My Solution :

假设s的长度为n, words的长度为m,一开始正常想的遍历时间复杂度是O(n)O(m^2)

然后进行优化

使用hashtable, 时间复杂度降为O(n)O(m)

一开始没有考虑到words可能存在重复的词语 使用Hashtable<String, Boolean>

后来改为Hashtable<String, Integer>

然而还是超过时间了,难受

//package pers.zhe.java.leetcode;import java.util.ArrayList;import java.util.Enumeration;import java.util.Hashtable;import java.util.List;public class Solution {public List<Integer> findSubstring(String s, String[] words) {List<Integer> result = new ArrayList<>();Hashtable<String, Integer> wordsMap = new Hashtable<>();        for (int x = 0; x < words.length; x++) {            if (wordsMap.containsKey(words[x])) {            wordsMap.put(words[x], wordsMap.get(words[x]) + 1);            } else {            wordsMap.put(words[x], 1);            }        }if (words.length == 0) {return result;}int wordLength = words[0].length();    int endIndex = s.length() - wordLength * words.length;        loop1 : for (int i = 0; i <= endIndex; i++) {        Hashtable<String, Integer> map = new Hashtable<>();                        for (int j = 0; j < words.length; j++) {            String temp = s.substring(i + wordLength * j, i + wordLength * j + wordLength);            if (wordsMap.containsKey(temp)) {                        if (map.containsKey(temp)) {            if (map.get(temp) < wordsMap.get(temp)) {            map.put(temp, map.get(temp) + 1);            } else {            continue loop1;            }            } else {            map.put(temp, 1);            }            } else {            continue loop1;            }            }                        Boolean allExist = true;            Enumeration<Integer> mapEnum = map.elements();            Enumeration<Integer> wordMapEnum = wordsMap.elements();            while(mapEnum.hasMoreElements()) {            if (mapEnum.nextElement() != wordMapEnum.nextElement()) {            allExist = false;            break;            }            }            if (allExist) {            result.add(i);            }        }           return result;    }}


Better Solution :

//package pers.zhe.java.leetcode;import java.util.ArrayList;import java.util.Enumeration;import java.util.Hashtable;import java.util.List;public class Solution {public static List<Integer> findSubstring(String S, String[] L) {    List<Integer> res = new ArrayList<Integer>();    if (S == null || L == null || L.length == 0) return res;    int len = L[0].length(); // length of each word        Map<String, Integer> map = new HashMap<String, Integer>(); // map for L    for (String w : L) map.put(w, map.containsKey(w) ? map.get(w) + 1 : 1);        for (int i = 0; i <= S.length() - len * L.length; i++) {        Map<String, Integer> copy = new HashMap<String, Integer>(map);        for (int j = 0; j < L.length; j++) { // checkc if match            String str = S.substring(i + j*len, i + j*len + len); // next word            if (copy.containsKey(str)) { // is in remaining words                int count = copy.get(str);                if (count == 1) copy.remove(str);                else copy.put(str, count - 1);                if (copy.isEmpty()) { // matches                    res.add(i);                    break;                }            } else break; // not in L        }    }    return res;}}




原创粉丝点击