• [LeetCode] 438. Find All Anagrams in a String 找出字符串中所有的变位词


    Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.

    Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

    The order of output does not matter.

    Example 1:

    Input:
    s: "cbaebabacd" p: "abc"
    
    Output:
    [0, 6]
    
    Explanation:
    The substring with start index = 0 is "cba", which is an anagram of "abc".
    The substring with start index = 6 is "bac", which is an anagram of "abc".

    Example 2:

    Input:
    s: "abab" p: "ab"
    
    Output:
    [0, 1, 2]
    
    Explanation:
    The substring with start index = 0 is "ab", which is an anagram of "ab".
    The substring with start index = 1 is "ba", which is an anagram of "ab".
    The substring with start index = 2 is "ab", which is an anagram of "ab".

    给一个字符串s和一个非空字符串p,找出s中所有的p的变位词的index。

    解法:滑动窗口法,双指针。

    Java:

    class Solution {
           public List<Integer> findAnagrams(String s, String p) {
               int left = 0;
               int right = 0;
               int matchSize = p.length();
               int[] map = new int[256];
               List<Integer> res = new ArrayList<>();
               // count the char number in p 计算p中各个字符的数量
               for (char c:p.toCharArray()){
                   map[c] ++;
               }
               
               
               // build window 开始进行sliding window
               while (right < s.length()){
                   // this char exists in p  
                   // 如果当前的char是存在于p中,则目标大小matchsize就得减少
                   // 判断标准就是他的值不是为-1
                   if (map[s.charAt(right)] > 0)
                       matchSize --;
                    map[s.charAt(right)] --;
                   
                   if (right - left == p.length()-1){
                       // check matchSize equals to 0
                       // 如果此时目标大小也是0,说明这就是需要的一个子串
                       if (matchSize == 0)
                           // add the left index
                           res.add(left);
                       
                       // move left pointer to start new search
                       // 如果当这个字符原来是p中的话,现在移动指针需要还原以前原有的matchSize,开始新的搜索
                       if (map[s.charAt(left)] >= 0)
                           matchSize ++;
                       // 还原以前每个元素减去的1
                       map[s.charAt(left)]++;
                       left++;
                   }
                  right++;
               }
               
               return res;
        }
    }
    

    Java:

    public class Solution {
        public List<Integer> findAnagrams(String s, String t) {
            List<Integer> result = new LinkedList<>();
            if(t.length()> s.length()) return result;
            Map<Character, Integer> map = new HashMap<>();
            for(char c : t.toCharArray()){
                map.put(c, map.getOrDefault(c, 0) + 1);
            }
            int counter = map.size();
            
            int begin = 0, end = 0;
            int head = 0;
            int len = Integer.MAX_VALUE;
            
            
            while(end < s.length()){
                char c = s.charAt(end);
                if( map.containsKey(c) ){
                    map.put(c, map.get(c)-1);
                    if(map.get(c) == 0) counter--;
                }
                end++;
                
                while(counter == 0){
                    char tempc = s.charAt(begin);
                    if(map.containsKey(tempc)){
                        map.put(tempc, map.get(tempc) + 1);
                        if(map.get(tempc) > 0){
                            counter++;
                        }
                    }
                    if(end-begin == t.length()){
                        result.add(begin);
                    }
                    begin++;
                }
                
            }
            return result;
        }
    } 

    Python:

    class Solution(object):
        def findAnagrams(self, s, p):
            """
            :type s: str
            :type p: str
            :rtype: List[int]
            """
            result = []
    
            cnts = [0] * 26
            for c in p:
                cnts[ord(c) - ord('a')] += 1
    
            left, right = 0, 0
            while right < len(s):
                cnts[ord(s[right]) - ord('a')] -= 1
                while left <= right and cnts[ord(s[right]) - ord('a')] < 0:
                    cnts[ord(s[left]) - ord('a')] += 1
                    left += 1
                if right - left + 1 == len(p):
                    result.append(left)
                right += 1
    
            return result
    

    Python: wo

    class Solution(object):
        def findAnagrams(self, s, p):
            """
            :type s: str
            :type p: str
            :rtype: List[int]
            """
            n = len(p)
            counts = [0] * 26
            for i in p:
                counts[ord(i) - ord('a')] += 1
                
            res = []
            for i in xrange(len(s)):
                counts[ord(s[i]) -  ord('a')] -= 1
                if i >= n:
                    counts[ord(s[i - n]) - ord('a')] += 1
                if self.checkAllZero(counts):
                    res.append(i - n + 1)
                
            return res            
                
        def checkAllZero(self, counts):           
            for i in counts:
                if i != 0:
                    return False
                
            return True   

    C++:

    // Time:  O(n)
    // Space: O(1)
    class Solution {
    public:
        vector<int> findAnagrams(string s, string p) {
            vector<int> result;
            if (p.empty() || s.empty()) {
                return result;
            }
    
            vector<int> cnts(26);
            for (const auto& c : p) {
                ++cnts[c - 'a'];
            }
            
            for (int left = 0, right = 0; right < s.length(); ++right) {
                --cnts[s[right] - 'a'];
                while (left <= right && cnts[s[right] - 'a'] < 0) {
                    ++cnts[s[left++] - 'a'];
                }
                if (right - left + 1 == p.length()) {
                    result.emplace_back(left);
                }
            }
            return result;
        }
    };
    

    C++:  

    class Solution {
    public:
        vector<int> findAnagrams(string s, string p) {
            if (s.empty()) return {};
            vector<int> res, m(256, 0);
            int left = 0, right = 0, cnt = p.size(), n = s.size();
            for (char c : p) ++m[c];
            while (right < n) {
                if (m[s[right++]]-- >= 1) --cnt;
                if (cnt == 0) res.push_back(left);
                if (right - left == p.size() && m[s[left++]]++ >= 0) ++cnt;
            }
            return res;
        }
    };
    

      

    类似题目:

    [LeetCode] 242. Valid Anagram 验证变位词

    [LeetCode] 567. Permutation in String 字符串中的全排列

     

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    Eclipse修改JSP文件的默认编码
    RPM常用命令总结
    软链接的妙用
    多线程练习
    Spring整合struts的配置文件存放问题
    使用struts框架后的404错误
    俄罗斯方块中的编程思想
    引用类型的强制类型转换
    数据库还原的问题
    常用sql语法初级
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9764318.html
Copyright © 2020-2023  润新知