zoukankan      html  css  js  c++  java
  • 30. 与所有单词相关联的字串、java实现

    题目描述:

    给定一个字符串 s 和一些长度相同的单词 words。在 s 中找出可以恰好串联 words 中所有单词的子串的起始位置。

    注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

    示例 1:
    输入:
     s = "barfoothefoobarman",
     words = ["foo","bar"]
    输出: 
      [0,9]
    
    解释: 从索引 0 和 9 开始的子串分别是 "barfoor" 和 "foobar" 。
    输出的顺序不重要, [9,0] 也是有效答案。
    

    示例 2:
    输入:
     s = "wordgoodstudentgoodword",
     words = ["word","student"]
    
    输出:
     []
    

    滑动窗口法:

        // 参考博客:
        // http://www.cnblogs.com/migoo/p/9454684.html
        // 用了滑动窗口的方法
        public List<Integer> findSubstring(String s, String[] words) {
            List<Integer> result = new ArrayList<Integer>();
            // 如果s,或者是words为空,那么也返回一个空的列表
            if (s.length() == 0 || s == null || words.length == 0 || words == null){
                return result;
            }
            int size = words[0].length(), length = words.length;
    
            // 把字符串数组中的的字符串全部插入HashMap中
            HashMap<String, Integer> map = generate(words);
            // 窗口的不同的起点,有size个不同的起点
            for (int i = 0; i < size; i++){
                HashMap<String, Integer> window= new HashMap<>();  // 一个滑动的窗口
                int left,right;
                left = right = i;
                while (right <= s.length() - size && left <= s.length() - length * size){
                    String word = s.substring(right, right + size);
                    incr(window, word);
                    if (!map.containsKey(word)){
                        window.clear();
                        right += size;
                        left = right;
                        continue;
                    }
                    while (window.get(word) > map.get(word)){
                        String w = s.substring(left, left + size);
                        decr(window, w);
                        left += size;
                    }
                    right += size;
                    if (right - left == size * length){
                        result.add(left);
                    }
                }
            }
            return result;
        }
        private HashMap<String, Integer> generate(String[] strs){
            HashMap<String, Integer> map = new HashMap<>();
            for (String str : strs){
                incr(map, str);
            }
            return map;
        }
    
        private void incr(HashMap<String, Integer> map, String str) {
            map.put(str, map.getOrDefault(str,0) + 1);
        }
        private void decr(HashMap<String, Integer> map, String str) {
            Integer num = map.get(str);
            if (num <= 1){
                map.remove(str);
            }else {
                map.put(str, num - 1);
            }
        }
    

    暴力法:

        // 参考博客
        // https://www.nowcoder.com/discuss/87526?type=0&order=0&pos=11&page=0
        // 暴力法
        public List<Integer> findSubstring(String s, String[] words) {
            List<Integer> result = new ArrayList<Integer>();
            if (s.length() == 0 || s == null || words.length == 0 || words == null){
                return result;
            }
            int size = words[0].length();
            int length = words.length;
            // 截取字符串时,取左不取右,所以这里的for循环中i的最大值可以取等号
            for (int i = 0; i <= s.length() - size * length; i++){
                HashMap<String, Integer> map = new HashMap<>();
                for (String word : words){
                    map.put(word, map.getOrDefault(word, 0) + 1);
                }
                if (check(s,i,map,size)){
                    result.add(i);
                }
            }
            return result;
        }
    
        private boolean check(String s, int i, HashMap<String, Integer> map, int size) {
            if (map.size() == 0){
                return true;
            }
            if (i > s.length() || i + size > s.length()){
                return false;
            }
            String word = s.substring(i, i + size);
            if (!map.containsKey(word)){
                return false;
            }else {
                Integer num = map.get(word);
                if (num <= 1){
                    map.remove(word);
                }else {
                    map.put(word, num - 1);
                }
    
               return check(s, i + size, map, size);
            }
        }
    
  • 相关阅读:
    什么是香港3c专线精品网和3c直连网络服务器
    服务器被攻击后处理办法
    服务器Linux系统安全维护基础知识介绍
    服务器宕机原因分析
    公网,专用,共享独立IP介绍
    服务器内存种类和各自特性
    自主组装服务器行不行
    英语网址大全收藏
    【分享】地产集团公司LOGO设计
    星际争霸2logo在线制作
  • 原文地址:https://www.cnblogs.com/daleyzou/p/9478836.html
Copyright © 2011-2022 走看看