• 30. Substring with Concatenation of All Words


        /*
         * 30. Substring with Concatenation of All Words
         * 2016-4-17 by Mingyang
         * 这道题目有一定的难度,我的思路是用一个map把对应的words和出现的次数写上去
         * 然后对于每一个位置就比较一下map中的个数并且更改
         * 首先第一个错误的地方是map的copy,我开始用的Hashmap a=b
         * 但是java是passing by value。所以应该新建一个object
         * 另外一个就是应该有个步长的变量
         */
         public static List<Integer> findSubstring(String s, String[] words) {
                int len=words.length;
                List<Integer> res=new ArrayList<Integer>();
                if(s==null||s.length()==0)
                  return res;
                int sumLen=0;
                int singleLen=words[0].length();
                HashMap<String,Integer> map=new HashMap<String,Integer>();
                for(int i=0;i<len;i++){
                  sumLen+=words[i].length();
                  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<=s.length()-sumLen;i++){
                    HashMap<String,Integer> temp=new HashMap<String,Integer>(map);
                    for(int j=i;j<i+sumLen;j=j+singleLen){
                        String key=s.substring(j,j+singleLen);
                        if(temp.containsKey(key)){
                            temp.put(key,temp.get(key)-1);
                            if(temp.get(key)==0){
                                temp.remove(key);
                            }
                        }else{
                            break;
                        }
                    }
                    if(temp.size()==0){
                        res.add(i);
                    }
                }
                return res;
            }    
         /*
         * 那么下面的代码更好!
         * http://blog.csdn.net/linhuanmars/article/details/20342851 非常难的一道题目
         */
             public List<Integer> findSubstring1(String S, String[] L) {
                 // Note: The Solution object is instantiated only once and is reused by
                 // each test case.
                 List<Integer> res = new ArrayList<Integer>();
                 if (S == null || S.length() == 0 || L == null || L.length == 0)
                     return res;
                 HashMap<String, Integer> map = new HashMap<String, Integer>();
                 for (int i = 0; i < L.length; i++) {
                     if (map.containsKey(L[i])) {
                         map.put(L[i], map.get(L[i]) + 1);
                     } else {
                         map.put(L[i], 1);
                     }
                 }
                 for (int i = 0; i < L[0].length(); i++) {
                     HashMap<String, Integer> curMap = new HashMap<String, Integer>();
                     int count = 0;
                     int left = i;
                     for (int j = i; j <= S.length() - L[0].length(); j += L[0].length()) {
                         String str = S.substring(j, j + L[0].length());
                         if (map.containsKey(str)) {
                             if (curMap.containsKey(str))
                                 curMap.put(str, curMap.get(str) + 1);
                             else
                                 curMap.put(str, 1);
                             if (curMap.get(str) <= map.get(str))
                             //这是正常的过程,不断加而没有越界
                                 count++;
                             else {
                             //这里出现了情况,加过头了,原则上就是重新回去更新left到不越界为止
                                 while (curMap.get(str) > map.get(str)) {
                                     String temp = S.substring(left,
                                             left + L[0].length());
                                     if (curMap.containsKey(temp)) {
                                         curMap.put(temp, curMap.get(temp) - 1);
                                         if (curMap.get(temp) < map.get(temp))
                                             count--;
                                     }
                                     left += L[0].length();
                                 }
                             }
                             //如果count达标那么就输出正确的结果!!
                             //注意!还没结束。还要滑动窗口继续下一个计算
                             if (count == L.length) {
                                 res.add(left);
                                 // if(left<)
                                 String temp = S.substring(left, left + L[0].length());
                                 if (curMap.containsKey(temp))
                                     curMap.put(temp, curMap.get(temp) - 1);
                                 count--;
                                 left += L[0].length();
                             }
                         } else {
                             //只要一个不满足条件。马上清零map,然后直接滑动窗口
                             curMap.clear();
                             count = 0;
                             left = j + L[0].length();
                         }
                     }
                 }
                 return res;
             }
             /*
              * 总结:我的代码跟大神的代码差别就是sliding window,下面代码各种情况下都是滑动窗口
              * 所以第一个for循环每一个i的值都是要遍历完所有的长度倍数上的点,而我只要一个不合适马上跳出来,
              * 这里只要一个不合适还继续在第二层循环里面滑动窗口
              */
  • 相关阅读:
    电商框架
    激光推送
    requirejs的用法(二)
    requirejs(一)
    AngularJs表单验证
    angularjs学习资料
    AngularJS内置指令
    angularjs 指令详解
    ASP.NET MVC5 + EF6 入门教程 (5) Model和Entity Framework
    EF框架step by step(9)—Code First Fluent API
  • 原文地址:https://www.cnblogs.com/zmyvszk/p/5403934.html
Copyright © 2020-2023  润新知