Anagram Substring Search

Given a text txt[0..n-1] and a pattern pat[0..m-1], write a function search(char pat[], char txt[]) that prints all occurrences of pat[] and its permutations (or anagrams) in txt[]. You may assume that n > m.

1) Input:  txt[] = "BACDGABCDA"  pat[] = "ABCD"
   Output:   Found at Index 0
             Found at Index 5
             Found at Index 6
2) Input: txt[] =  "AAABABAA" pat[] = "AABA"
   Output:   Found at Index 0
             Found at Index 1
             Found at Index 4

统计字母频率

复杂度

时间 O(NM) 空间 O(1)

思路

用一个256位的数组统计Pattern字符串中每一个字符出现的次数,然后同理,维护一个长度为Pattern长度的窗口,来统计这个窗口里母串各个字符出现的次数,计入一个数组中。比较这两个数组是否相同就知道是否是变形词子串了。窗口向右移动一位时,加上新来的字符,减去刚离开窗口的字符。

代码

public class AnagramSubstring {
    
    public static void main(String[] args){
        System.out.println(findSubstring("BACDGABCDA", "ABCD"));
        
    }
    
    public static List<Integer> findSubstring(String str, String ptn){
        List<Integer> res = new LinkedList<Integer>();
        // 一个数组统计Pattern的字符出现次数
        int[] pntcnt = new int[256];
        // 一个数字统计窗口内的字符出现次数
        int[] strcnt = new int[256];
        for(int i = 0; i < ptn.length(); i++){
            pntcnt[ptn.charAt(i)]++;
        }
        int i = 0;
        for(i = 0; i < ptn.length() && i < str.length(); i++){
            strcnt[str.charAt(i)]++;
        }
        if(isSame(pntcnt, strcnt)){
            res.add(i - ptn.length());
        }
        while(i < str.length()){
            // 新来一个字符,自增其出现次数
            strcnt[str.charAt(i)]++;
            // 将离开窗口的字符次数减一
            strcnt[str.charAt(i - ptn.length())]--;
            i++;
            // 判断两个数组是否相同
            if(isSame(pntcnt, strcnt)){
                res.add(i - ptn.length());
            }
        }
        return res;
    }
    
    public static boolean isSame(int[] arr1, int[] arr2){
        if(arr1.length != arr2.length) return false;
        for(int i = 0; i < arr1.length; i++){
            if(arr1[i] != arr2[i]) return false;
        }
        return true;
    }
}

ethannnli
858 声望360 粉丝