zoukankan      html  css  js  c++  java
  • Substring with Concatenation of All Words, 返回字符串中包含字符串数组所有字符串元素连接而成的字串的位置

    问题描述:给定一个字符数组words,和字符串s,返回字符数组中所有字符元素组成的子串在字符串中的位置,要求所有的字符串数组里的元素只在字符串s中存在一次。

    算法分析:这道题和strStr很类似。只不过strStr是子串,而这个题是字符串数组里的元素组成的子串,字符串数组里的元素是无序的,但是必须全部包含。所有考虑使用map集合。关键点在于几个临界值,字符串元素在s中重复了怎么做,找到一个符合的子串后怎么做,有字符串元素不匹配怎做。

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    
    public class SubstringwithConcatenationofAllWords {
        
        public List<Integer> findSubstring(String s, String[] words) {
            
            ArrayList<Integer> result = new ArrayList<Integer>();
            if(s==null||s.length()==0||words==null||words.length==0){
                return result;
            } 
         
            //frequency of words
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            for(String w: words){
                if(map.containsKey(w)){
                    map.put(w, map.get(w)+1);
                }else{
                    map.put(w, 1);
                }
            }
         
            int len = words[0].length();
         
            for(int j=0; j<len; j++)
            {
                HashMap<String, Integer> currentMap = new HashMap<String, Integer>();
                int start = j;//起始下标,因为len为窗口大小,所以起始下标只需在0-len之间循环,就像取模一样,超过了,就重复了。
                int count = 0;//记录满足的字符串数量
         
                for(int i=j; i<=s.length()-len; i=i+len)
                {
                    String sub = s.substring(i, i+len);
                    if(map.containsKey(sub))
                    {
                        if(currentMap.containsKey(sub))
                        {
                            currentMap.put(sub, currentMap.get(sub)+1);
                        }
                        else
                        {
                            currentMap.put(sub, 1);
                        }
         
                        count++;
                        //只要发现子字符串中有重复的字符数组中的元素,那么就从起始位置循环删除字符串.
                        //也就是说重复了,就逆向操作,直至只包含一个重复的那个字符串。
                        while(currentMap.get(sub)>map.get(sub))
                        {
                            //四个基本逆向操作。重复了或匹配成功了都要进行窗口滑动。
                            String left = s.substring(start, start+len);
                            currentMap.put(left, currentMap.get(left)-1);
                            count--;
                            start = start + len;
                        }
         
         
                        if(count==words.length)//字符串包含所有字符数组中的元素,
                        {
                            result.add(start); //将起始位置加入result
                            //四个基本逆向操作。窗口滑动。窗口值为len
                            String left = s.substring(start, start+len);
                            currentMap.put(left, currentMap.get(left)-1);
                            count--;
                            start = start + len;
                        }
                    }
                    else
                    {
                        currentMap.clear();
                        start = i+len;
                        count = 0;
                    }
                }
            }
         
            return result;
        }
    }

    StrStr算法如下:

    public int strStr(String haystack, String needle) {
            
            if(haystack == null || needle == null)
            {
                return -1;
            }
            
            for (int i = 0; i <= (haystack.length()-needle.length()); i++) 
            {
                int m = i;
                for (int j = 0; j < needle.length(); j++) 
                {
                    if (needle.charAt(j) == haystack.charAt(m)) 
                    {
                        m++;
                        if((m-i) == needle.length())
                        {
                            return i;
                        }
                    } 
                    else 
                    {
                        break;
                    }
                }
            }
            return -1;
        }
  • 相关阅读:
    [Redis]主从同步可能遇到的坑
    Redis_如何保证原子操作
    .Net Core 5.0 Json序列化和反序列化 | System.Text.Json 的json序列化和反序列化
    JavaScript Error对象整理_JavaScript 异常处理整理
    Canvas 事件绑定|Canvas事件处理
    Css3 常用布局方式 一行两列&高度自适应&垂直方向居中
    Css3 实现锯齿效果整理
    Css3 currentColor 变量使用
    Css3 实现任意角扇形|Css3实现六角扇形
    实现 Application_Start 和 Application_End
  • 原文地址:https://www.cnblogs.com/masterlibin/p/5559635.html
Copyright © 2011-2022 走看看