leetcode每日一题之30.Substring with Concatenation of All Words(续)


thumbnail: https://s2.ax1x.com/2019/04/05/ARfLq0.jpg
title: 30.Substring with Concatenation of All Words(续)
toc: true
tags: leetcode
categories: leetcode
comments: true


题目描述:与所有单词相关联的子串

      给定一个子串s和一些长度相同的单词组成的字符串数组words.
注意:
      在s中找出恰好串联words中所有单词的子串的起始位置,中间不能有其他字符,但不要考虑words中单词串联的顺序.
上篇我们讨论了本题的一种暴力求解法,本篇接着讨论另外两种优化的解法.


解法二:

      本方法遍历子串时,同解法一不同之处在于,子串与给定单词字符串数组words的匹配规则不同.解法一是利用子串组成的数组和给定words的排序结果的内容相同来判断子串是否满足要求;而解法二利用了map,首先将words中单词与单词频次转化为key-value的形式,遍历s时得到的子串按同理存于另一个map里面,判断这两个map是否相等,以此决定该子串是否满足要求。


java源程序:

class Solution {
    public List findSubstring(String s, String[] words) {
        int sLen = s.length();
        int unit = words.length;
        List res = new LinkedList<>();
        if(unit==0 || sLen==0) return res;
        int wLen = words[0].length();
        int wordsLen = unit*wLen;
        Map map = new HashMap<>();

        for(String word:words){
            map.put(word,map.getOrDefault(word,0)+1);

        }

        for(int i=0;i temp = new HashMap<>(map);
            int j=0;
            for(;j

运行时间和空间如下图:

解法二时间空间复杂度


解法三:

      解法三与解法二判断子串和words是否匹配的方法一样,但是遍历子串的方式有所不同.在第一层循环中,以一个字符为单位,遍历次数为wLen,在第二层循环中,以wLen为一单位,比较当前子串第一个长度为wLen的单词与其后长度为wLen的单词是否相同,相同就维持未来字符串不变,这样,如果匹配成功的话,索引位置就对应于子串首次出现的位置;如果不同,删除子串第一个单词,加入子串后的一个单词,形成一个新的子串.两层循环下,可以将所有的情况遍历完,重要的是,第二层循环的处理减少了map的频繁操作,从而降低了时间的复杂度。


java源程序:

class Solution {
    public List findSubstring(String s, String[] words) {
        int sLen = s.length();
        int unit = words.length;
        List res = new LinkedList<>();
        if(unit==0 || sLen==0) return res;
        int wLen = words[0].length();
        int wordsLen = unit*wLen;
        Map map = new HashMap<>();
        for(String word:words){
            map.put(word,map.getOrDefault(word,0)+1);
        }
        for(int i=0;i temp = new HashMap<>();
            for(int k=0;k

运行时间和空间如下图:


解法三时间空间复杂度

你可能感兴趣的:(leetcode每日一题之30.Substring with Concatenation of All Words(续))