码迷,mamicode.com
首页 > 其他好文 > 详细

从一道Hard学习滑动窗口

时间:2019-11-15 12:14:42      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:bsp   result   new   Matter   har   null   rac   操作   png   

滑动窗口


  滑动窗口(sliding windows algorithm)这种方法,专门用于解决区间解的问题。它在运算的时候,将解集放在窗口中,结束的时候比对是否符合预期。在运算的过程中,会对窗口的左右边缘进行操作(扩大、缩小)。特别针对于线性输入解决,滑动窗口就很形象了。

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 starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

  题意是从一串输入字符串s中,找到能全包含words数组的起点(数组元素等长),这个起点可能有多个,而且不需要关心顺序。

Input:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoo" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.

  比如这个例子,他在第0个位置和第9个位置可以包含words数组,也就是0位置和9位置各有一个长度为6的窗口可以囊括words数组。

技术图片

 

技术图片

 

   每次扩展使用单词列表中的词长,如果扩展过程中不符合预期则清除窗口,窗口左端在当前词总数大于词组总数的时候,计算总数是单词的长度(因为s除以单词长度余数是0到单词长度之间,覆盖了余数就能覆盖整个场景)。

public class FindSubstring {
    public void test(){
        // [0,9]
        String s1 = "barfoothefoobarman";
        String[] words1 = {"foo","bar"};
        System.out.println(findSubstring(s1,words1));
        // []
        String s2 = "wordgoodgoodgoodbestword";
        String[] words2  = {"word","good","best","word"};
        System.out.println(findSubstring(s2,words2));
    }
    /**
     *  单词等长
     */
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> result = new ArrayList<>();
        if(s == null || words.length == 0){
            return result;
        }
        int step = words[0].length();
        Map<String,Integer> counter = new HashMap<>();
        for(String word :words){
            counter.merge(word, 1, (a, b) -> a + b);
        }

        for(int i=0;i<step;++i){
            Map<String,Integer> window = new HashMap<>();
            int left = i;
            int right = i;
            while (right <= s.length() - step && left <= s.length() - step*words.length){
                String sub = s.substring(right,right + step);
                window.merge(sub,1,(a , b)->a + b);
                if(!counter.containsKey(sub)){
                    window.clear();
                    right += step;
                    left = right;
                    continue;
                }
                while (window.get(sub) > counter.get(sub)){
                    String drop = s.substring(left,left+step);
                    Integer dec = window.get(drop);
                    if(dec != null){
                        if(dec<=1){
                            window.remove(drop);
                        }else {
                            window.put(drop,dec-1);
                        }
                    }
                    left += step;
                }
                right += step;
                if(right - left == step * words.length){
                    result.add(left);
                }
            }
        }
        return result;
    }

}

 

 

技术图片

 

 

 

从一道Hard学习滑动窗口

标签:bsp   result   new   Matter   har   null   rac   操作   png   

原文地址:https://www.cnblogs.com/chentingk/p/11865392.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!