• 30. Substring with Concatenation of All Words


    一、题目

      1、审题

        

      2、分析

        给出一个字符串 S, 一个字符串单词数组 words(所有单词均等长),在S中找到包含words中所有单词且只包含一次的子字符串,返回符合该要求的所有子串的首位置word中的字符串可能会有重复。

    二、解答

      1、思路:

        实现一:  通过暴力的方法依次截取 S 中的字符串进行判断是否包含了 words 中的所有元素。借助 Map 进行存放 words 中元素,从而判断是否包含所有元素。

    class Solution {
        public List<Integer> findSubstring(String s, String[] words) {
    
            Map<String, Integer> mapOfWords = new HashMap<String, Integer>();
            
            int wordsLen = words.length;    // 字符串个数
            int slen = s.length();
            int i, j, count = wordsLen;
            boolean countChanged = false;   // 判断是否改变了 map 中的值,如果没改变则无需初始化
            List<Integer> result = new ArrayList<Integer>();
        
            if(wordsLen == 0 || slen == 0)
                return result;
            int singleWordLen = words[0].length();  // 单个字符串长度
    
            initializeMap(mapOfWords, words);
    
            for (i = 0; i <= slen - wordsLen*singleWordLen; i++) {
                String subStr = s.substring(i, i + singleWordLen);  // 取出一个子串
    
                j = i;
                if(mapOfWords.containsKey(subStr) )
                    while (mapOfWords.get(subStr) != 0) {
    
                        mapOfWords.put(subStr, mapOfWords.get(subStr) - 1);   // 值 - 1
                        count--;
                        countChanged = true;
                        j += singleWordLen;
    
                        if(j + singleWordLen > slen)
                            break;
                        subStr = s.substring(j, j + singleWordLen); // 下一个字符串
                        if (!mapOfWords.containsKey(subStr))
                            break;
                    }
    
                if(count == 0)  //找齐所有字符串数组中的字串后把该索引压入;
                    result.add(i);
    
                if(countChanged) {      //若改变了map的值需要重新初始化map和count
                    mapOfWords.clear();
                    initializeMap(mapOfWords, words);
                    count = wordsLen;
                    countChanged = false;
                }
            }
            return result;
        }
        
        public void initializeMap(Map<String, Integer> mapOfWords, String[] words) {
    
            for (int i = 0; i < words.length; i++) {    //初始化map
                if(mapOfWords.containsKey(words[i])) {
                    mapOfWords.put(words[i], mapOfWords.get(words[i]) + 1);
                }
                else {
                    mapOfWords.put(words[i], 1);
                }
            }
        }
    }

        实现二:  通过两个 Map 来实现代码的简化,一个 Map 存放数组的字符串及其出现个数,另一个存放遍历的字符串中出现的数组元素的情况。每次遍历一个 S 的子串只需将 两个Map 进行对比,即可判断该字符串是否符合要求。

    public class Solution {
        public List<Integer> findSubstring(String s, String[] words) {
            List<Integer> list = new ArrayList<Integer>();
            Map<String, Integer> map = new HashMap<String, Integer>();
            Map<String, Integer> tmp = new HashMap<String, Integer>();
            
            int sLength = s.length();
            int wordsNum = words.length;
            int wordslength = words[0].length();
            int j;
            
            if(sLength < wordsNum || wordsNum == 0) 
                return list;
            for(int i = 0; i < wordsNum; i++) {
                if(map.containsKey(words[i]))
                    map.put(words[i], map.get(words[i]) + 1);
                else
                    map.put(words[i], 1);
            }
            
            for (int i = 0; i <= sLength-wordsNum*wordslength; i++) {
                tmp.clear();
                for(j = 0; j < wordsNum; j++) {
                    String word = s.substring(i+j*wordslength, i + j*wordslength+wordslength);
                    
                    if(!map.containsKey(word)) 
                        break;
                    
                    // 可能有重复
                    if(tmp.containsKey(word))
                        tmp.put(word, tmp.get(word)+1);
                    else
                        tmp.put(word, 1);
                    
                    if(tmp.get(word) > map.get(word))
                        break;
                }
                
                if(j == wordsNum)
                    list.add(i);
            }
            
            return list;
        }
    
         
    }
  • 相关阅读:
    AES密码算法详解(转自https://www.cnblogs.com/luop/p/4334160.html)
    快速排序和插入排序——我的代码
    北京大学1001ACM——高精度类型题总结
    C语言数组不知道输入几个整数以及输入一直到为0
    C语言并查集例子——图问题巧用parent[]数组
    C语言快速判断素数——不超时
    C语言如何才能使用bool类型
    C语言两个特别大的整数类型相加超出范围使用两个技巧
    C语言存30位数字长的十进制方法
    dockerfile相关命令
  • 原文地址:https://www.cnblogs.com/skillking/p/9435017.html
Copyright © 2020-2023  润新知