题目:

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 intervening characters.

For example, given:
S: "barfoothefoobarman"
L: ["foo", "bar"]

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

 

题解:

我最开始做的是说把L里面给的串全排列放起来,看S包含不包含其中之一,包含的话反话其index。但是这个方法TLE了

代码:

  1.  1    public static void swap(String[] str, int i, int j){  
  2.  2         String temp = new String();  
  3.  3         temp = str[i];  
  4.  4         str[i] = str[j];  
  5.  5         str[j] = temp; 
  6.  6     } 
  7.  7     
  8.  8     public static void arrange (String[] L, int st, ArrayList<String> re){
  9.  9         if (st == L.length - 1){
  10.              String temp = new String();
  11.              for (int i = 0; i < L.length; i ++){
  12.                  temp +=L[i];
  13.              }  
  14.              re.add(temp);
  15.          }else{
  16.              for (int i = st; i < L.length; i ++){  
  17.                  swap(L, st, i);  
  18.                  arrange(L, st + 1,re);  
  19.                  swap(L, st, i);  
  20.              }  
  21.          }  
  22.          return ;
  23.      }  
  24.      public static ArrayList<Integer> findSubstring(String S, String[] L) {
  25.          ArrayList<Integer> result = new ArrayList<Integer>();
  26.          ArrayList<String> possible = new ArrayList<String>();
  27.          arrange(L,0,possible);
  28.          
  29.          for(int j= 0; j<possible.size();j++){
  30.              if(S.contains(possible.get(j)))
  31.                  result.add(S.indexOf(possible.get(j)));     
  32.          }
  33.         
  34.          return result;
  35.      }

更好的解法就是一种滑动窗口式的。我是参照了http://blog.csdn.net/linhuanmars/article/details/20342851的写法,他的写法目前速度最快。

首先是先把所给的字典利用HashMap建一下,key存word,value存这个word出现的个数。

因为每个单词长度一样,外层循序只许循环wordLen次,每次指针挪一次,每一次循环遍历整个字符串。

内层循环每次遍历一个单词,把整个S字符串遍历检查。

需要在每次大循环维护一个count,看是不是达到了给的字典字符串数量,同时维护一个index,是每个符合条件的字符串的起始index,需要存到返回结果中。

为了能够检查是不是合格字符串,在这里维护一个curDict的HashMap。

首先检查一个单词是不是在原始字典中出现,没出现的话说明这个单词肯定不符合标准,index指针指向下一个单词的起始点,计数器和curDict都要清零。

如果这个单词在原始字典里出现过,用更新原始字典的方法更新curDict,如果这个单词出现的次数没有超过原始字典里记录的次数,那么count++,如果超过了,就需要挪动指针,并把超过的从curDict删掉。

最后,如果count达到了L的length,说明找到了一个合格的字符串,那么将index存入返回结果res中,再把index挪到下一个单词处,更新curDict即可。

code ganker的讲解是这样的:

这道题看似比较复杂,其实思路和Longest
Substring Without Repeating Characters
差不多。因为那些单词是定长的,所以本质上和单一个字符一样。和Longest
Substring Without Repeating Characters

区别只在于我们需要维护一个字典,然后保证目前的串包含字典里面的单词有且仅有一次。思路仍然是维护一个窗口,如果当前单词在字典中,则继续移动窗口右
端,否则窗口左端可以跳到字符串下一个单词了。假设源字符串的长度为n,字典中单词的长度为l。因为不是一个字符,所以我们需要对源字符串所有长度为l的
子串进行判断。做法是i从0到l-1个字符开始,得到开始index分别为i,
i+l, i+2*l,
...的长度为l的单词。这样就可以保证判断到所有的满足条件的串。因为每次扫描的时间复杂度是O(2*n/l)(每个单词不会被访问多于两次,一次是窗
口右端,一次是窗口左端),总共扫描l次(i=0, ...,
l-1),所以总复杂度是O(2*n/l*l)=O(n),是一个线性算法。空间复杂度是字典的大小,即O(m*l),其中m是字典的单词数量。

代码部分我自己稍作了修改,主题思想与code ganker相同。

代码如下:

  1.  1      public static ArrayList<Integer> findSubstring(String S, String[] L) { 
  2.  2          ArrayList<Integer> res = new ArrayList<Integer>();
  3.  3          if(S==null||L==null||S.length()==0||L.length==0)
  4.  4             return res;
  5.  5          int wordLen = L[0].length();//same length for each word in dictionary
  6.  6          
  7.  7          //put given dictionary into hashmap with each word's count
  8.  8          HashMap<String, Integer> dict = new HashMap<String, Integer>();
  9.  9          for(String word: L){
  10.               if(!dict.containsKey(word))
  11.                  dict.put(word, 1);
  12.               else
  13.                  dict.put(word, dict.get(word) + 1);
  14.           }
  15.           
  16.           for(int i = 0; i < wordLen; i++){
  17.               int count = 0;
  18.               int index = i;//index of each startpoint
  19.               HashMap<String, Integer> curdict = new HashMap<String, Integer>();
  20.               //till the first letter of last word 
  21.               for(int j = i; j <= S.length() - wordLen; j += wordLen){
  22.                   String curWord = S.substring(j, j + wordLen);
  23.                   //check each word to tell if it existes in give dictionary
  24.                   if(!dict.containsKey(curWord)){
  25.                       curdict.clear();
  26.                       count = 0;
  27.                       index = j + wordLen;
  28.                   }else{
  29.                       //form current dictionary
  30.                       if(!curdict.containsKey(curWord))
  31.                          curdict.put(curWord, 1);
  32.                       else
  33.                          curdict.put(curWord, curdict.get(curWord) + 1);
  34.                       
  35.                       //count for current found word and check if it exceed given word count
  36.                       if(curdict.get(curWord) <= dict.get(curWord)){
  37.                           count++;
  38.                       }else{
  39.                           while(curdict.get(curWord) > dict.get(curWord)){
  40.                               String temp = S.substring(index, index + wordLen);
  41.                               curdict.put(temp, curdict.get(temp)-1);
  42.                               index = index + wordLen;//make index move next
  43.                           }
  44.                       }
  45.                       
  46.                       //put into res and move index point to nextword 
  47.                       //and update current dictionary as well as count num
  48.                       if(count == L.length){
  49.                           res.add(index);
  50.                           String temp = S.substring(index, index + wordLen);
  51.                           curdict.put(temp, curdict.get(temp)-1);
  52.                           index = index + wordLen;
  53.                           count--;
  54.                       }
  55.                   }
  56.               }//end for j
  57.           }//end for i
  58.            return res;
  59.          } 

Substring with Concatenation of All Words leetcode java的更多相关文章

  1. [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 sta ...

  2. leetcode面试准备: Substring with Concatenation of All Words

    leetcode面试准备: Substring with Concatenation of All Words 1 题目 You are given a string, s, and a list o ...

  3. [Leetcode][Python]30: Substring with Concatenation of All Words

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 30: Substring with Concatenation of All ...

  4. 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 ar ...

  5. 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, tha ...

  6. LeetCode HashTable 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 sta ...

  7. 【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 ar ...

  8. LeetCode - 30. Substring with Concatenation of All Words

    30. Substring with Concatenation of All Words Problem's Link --------------------------------------- ...

  9. Minimum Window Substring leetcode java

    题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...

随机推荐

  1. -bash: sdk: command not found

    Mac上安装过sdkman 但是由于某种原因使环境变量丢失久会出现使用sdk命令时 出现-bash: sdk: command not found提示 从新按照教程安装又提示电脑上sdkman已经安装 ...

  2. centOS7 apache ssl证书安装配置

    背景说明:服务器是centOS7.4 七牛申请的免费ssl证书 默认apache是没有安装SSL模块的,所以需要安装,接着使用命令: yum install -y mod_ssl apache目录 / ...

  3. hdu 4540 dp

    题意: 假设: 1.每一个时刻我们只能打一只地鼠,并且打完以后该时刻出现的所有地鼠都会立刻消失: 2.老鼠出现的位置在一条直线上,如果上一个时刻我们在x1位置打地鼠,下一个时刻我们在x2位置打地鼠,那 ...

  4. Codeforces Round #259 (Div. 1) A. Little Pony and Expected Maximum 数学公式结论找规律水题

    A. Little Pony and Expected Maximum Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.c ...

  5. centos7安装zookeeper3.4.9集群

    本篇文章目的:以最小成本学习zookeeper的集群安装. zookeeper的三要素: 1.一致,能够保证数据的一致性 2.有头,始终有一个leader,node/2+1个节点有效,就能正常工作 3 ...

  6. Git_Feature分支

    软件开发中,总有无穷无尽的新的功能要不断添加进来. 添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合 ...

  7. LAMP LNMP 和 LNMPA

    LAMP指的是:Linux+Apache+MySQL+Perl/PHP/Python LAMP是一个缩写,它指一组通常一起使用来运行动态网站或者服务器的自由软件: Linux,操作系统: Apache ...

  8. 修改WampServer的默认端口

    WampServer默认的安装端口是80,容易和已安装的ISS等其他服务冲突,导致WampServer无法启动. 无法启动的现象如下: 1.apache服务无法启动.问题所在:80端口冲突. 2.在浏 ...

  9. solaris 10系统配置工具

    bash-3.2# prtdiag 报告一般系统信息 System Configuration: VMware, Inc. VMware Virtual Platform BIOS Configura ...

  10. 获取WINDOWS打印机列表

    获取WINDOWS打印机列表 如何知道WINDOWS已经安装了哪些打印机? 1) usesVcl.Printers 2) Printer.Printers  // property Printers: ...