Home > Net >  Find All Anagrams in a String TLE
Find All Anagrams in a String TLE

Time:08-05

Given two strings s and p, return an array of all the start indices of p's anagrams in s. You may return the answer in any order.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Getting TEL for below code. What's wrong with my code?

import java.util.*;
    public class FindAllAnagramsInAString_438{
        public static void main(String[] args){
            String s="abab";
            String p="ab";
            // String s="cbaebabacd";
            // String p="abc";
            System.out.println(findAnagrams(s,p));
        }
        public static List<Integer> findAnagrams(String s, String p) {
            int i=0;
            int j=p.length();
            List<Integer> list=new ArrayList<>();
            while(j<=s.length()){
                //System.out.println("Substring >>" s.substring(i,j));
                if(isAnamgram(s.substring(i,j),p)){
                    list.add(i);
                }
                i  ;
                j  ;
            }
            return list;
        }
        public static boolean isAnamgram(String s,String p){
            HashMap<Character,Integer> map=new HashMap<>();
            if(s.length()!=p.length()) return false;
            for(int i=0;i<s.length();i  ){
                char chs=s.charAt(i);
                char chp=p.charAt(i);
                map.put(chs,map.getOrDefault(chs,0) 1);
                map.put(chp,map.getOrDefault(chp,0)-1);
            }
            for(int val:map.values()){
                if(val!=0) return false;
            }
            return true;
        }
    }

CodePudding user response:

You shouldn't be creating a whole new frequency table for each substring. Given a table for index i, the table for index i 1 changes by only 2 counts. Just modify the previous table to get the next one. Also don't bother counting characters that don't appear in the search string.

Also, don't do the whole table comparison -- just keep track of the number of mismatched counts. Again this changes by at most 2 counts per index.

Finally, don't allocate a new substring for each index.

CodePudding user response:

Looks good now

HashMap<Character,Integer> pMap=new HashMap<>();
        HashMap<Character,Integer> sMap=new HashMap<>();
        List<Integer> list=new ArrayList<>();
        for(int i=0;i<p.length();i  ){
            char ch=p.charAt(i);
            pMap.put(ch,pMap.getOrDefault(ch,0) 1);
        }
        int j=0;
        while(j<p.length()){
            char ch=s.charAt(j);
            sMap.put(ch,sMap.getOrDefault(ch,0) 1);
            j  ;
        }
        int i=0;
        while(j<s.length()){
            if(pMap.equals(sMap)){
                list.add(i);
            }
            sMap.put(s.charAt(j),sMap.getOrDefault(s.charAt(j),0) 1);
            if((sMap.getOrDefault(s.charAt(i),0)-1)==0){
                sMap.remove(s.charAt(i));
            }else{
                sMap.put(s.charAt(i),sMap.getOrDefault(s.charAt(i),0)-1);
            }
            i  ;
            j  ;
        }
        return list;
  • Related