• Leetcode: 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 intervening characters.
    
    For example, given:
    S: "barfoothefoobarman"
    L: ["foo", "bar"]

    这道题想的时候颇费了一些周折,想过把L的所有concatenation组合出来,放到hash或map里,然后遍历S的时候直接看。但是这样如果L的size: Lsize过大的话,可能的组合有Lsize!种,组合数剧增,效率低下,所以不采用这种方法。

    又考虑在S中从左向右一个word一个word遍历过去,一次只取L中一个word的大小,存入Hashmap,如果匹配到了L,则算找到了一种可能的concatenation;这样也有缺点,比如L为foo the kgm tim cog, S为bar foo tim cog kgm tim foo the, S遍历到第二个tim时出现不匹配,所以我的指针得跳到第一个tim的下一个,才能不漏掉所有的可能性。我要想跳到第一个tim得存下它的位置,这就要求hashmap的value为元素位置,这就导致我不好进行匹配,因为L若要存为一个hashmap,它的value我无法确定

    所以参考网上有了第三种做法,先把L中的word存入一个Hashmap, 记录每个word的出现次数,然后在S中从左向右挨个遍历过去,每次取wsize * Lsize个字母分成Lsize份存入Hashmap中,每份大小为wsize, 然后比较这个Hashmap与L的Hashmap是否一致

     1 import java.util.*;
     2 
     3 public class Solution {
     4     public List<Integer> findSubstring(String S, String[] L) {
     5         ArrayList<Integer> result = new ArrayList<Integer>();
     6         if (S.length() == 0 || L.length == 0) return result;
     7         Hashtable<String, Integer> obj = new Hashtable<String, Integer>();
     8         Hashtable<String, Integer> real = new Hashtable<String, Integer>();
     9         int Lsize = L.length;
    10         int wsize = L[0].length();
    11         for (String a : L) {
    12             if (obj.containsKey(a)) {
    13                 int k = obj.get(a);
    14                 obj.put(a, k+1);
    15             }
    16             else obj.put(a, 1);
    17         }
    18         
    19         for (int i = 0; i <= S.length() - Lsize * wsize; i++) {
    20             real.clear();
    21             for (int j = 0; j <= Lsize - 1; j++) {
    22                 String temp = S.substring(i + j * wsize, i + (j+1) * wsize);
               if (!obj.containsKey(temp)) break;
    23 if (real.containsKey(temp)) { 24 int m = real.get(temp); 25 real.put(temp, m+1); 26 } 27 else real.put(temp, 1); 28 } 29 if (real.equals(obj)) { 30 result.add(i); 31 } 32 } 33 34 return result; 35 } 36 }

     另一个版本,也许更好懂一点

     1 public class Solution {
     2     public List<Integer> findSubstring(String S, String[] L) {
     3         ArrayList<Integer> res = new ArrayList<Integer>();
     4         HashMap<String, Integer> target = new HashMap<String, Integer>();
     5         HashMap<String, Integer> real = new HashMap<String, Integer>();
     6         for (String str : L) {
     7             if (target.containsKey(str)) {
     8                 int val = target.get(str);
     9                 target.put(str, val+1);
    10             }
    11             else {
    12                 target.put(str, 1);
    13             }
    14         }
    15         
    16         int wSize = L[0].length();
    17         int lSize = L.length;
    18         for (int i=0; i<=S.length()-lSize*wSize; i++) {
    19             for (int j=i; j<=i+lSize*wSize-1; j=j+wSize) {
    20                 String temp = S.substring(j, j+wSize);
    21                 if (!target.containsKey(temp)) break;
    22                 if (real.containsKey(temp)) {
    23                     int value = real.get(temp);
    24                     real.put(temp, value+1);
    25                 }
    26                 else {
    27                     real.put(temp, 1);
    28                 }
    29             }
    30             if (real.equals(target)) {
    31                 res.add(i);
    32             }
    33             real.clear();
    34         }
    35         return res;
    36     }
    37 }
  • 相关阅读:
    TCP的三次握手与四次挥手
    HashMap源代码分析(JDK1.8)
    HashMap实现原理分析(JDK1.8前)
    codebook法分割前景目标
    平均场景法分割前景目标
    边缘梯度方向直方图的构建
    学习opencv 第六章 习题十三
    《学习OpenCV》 第四章 习题六
    《学习Opencv》第五章 习题6
    Opencv实现的简易绘图工具
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/3787810.html
Copyright © 2020-2023  润新知