题目描述
因为自己写的复杂度已经到了 O(n),就没有再参考题解的优化了 更新:滑动窗口方法
思路 & 代码
用一个 int[ ] count 来存储当前判断子串的各字母出现次数 getCount():对当前子串,求 count,时间复杂度 O(n) formatString():用 count 转换成当前子串的对比格式 ,时间复杂度 O(1) 对比格式:如"abcccz" 变成 “a1b1c3z1” 实际上,getCount只要使用两次即可:一次给 p,一次给 s 的第一个子串 往后,s 的字串只需要对之前的 count 进行微小更新即可
class Solution { public List < Integer > findAnagrams ( String s, String p) { List < Integer > ans = new ArrayList < > ( ) ; int pLen = p. length ( ) ; if ( s. length ( ) < pLen) { return ans; } char [ ] sC = s. toCharArray ( ) ; char [ ] pC = p. toCharArray ( ) ; int [ ] count = new int [ 26 ] ; getCount ( pC, count) ; String formatP = formatString ( count) ; count = new int [ 26 ] ; getCount ( s. substring ( 0 , pLen) . toCharArray ( ) , count) ; String formatQ = formatString ( count) ; if ( formatQ. equals ( formatP) ) { ans. add ( 0 ) ; } for ( int i = 1 ; i + pLen <= s. length ( ) ; i++ ) { char last = sC[ i + pLen - 1 ] ; char pre = sC[ i - 1 ] ; if ( last != pre) { count[ last - 'a' ] ++ ; count[ pre - 'a' ] -- ; formatQ = formatString ( count) ; } if ( formatQ. equals ( formatP) ) { ans. add ( i) ; } } return ans; } void getCount ( char [ ] now, int [ ] count) { for ( char ch : now) { count[ ch - 'a' ] ++ ; } } String formatString ( int [ ] count) { StringBuilder formatNow = new StringBuilder ( ) ; for ( int i = 0 ; i < 26 ; i++ ) { if ( count[ i] != 0 ) { formatNow. append ( ( char ) ( i + 'a' ) ) ; formatNow. append ( count[ i] ) ; } } return formatNow. toString ( ) ; }
}
更新版
现在看之前的代码简直不堪入目…好长好冗余 新思路:等大滑动窗口,数组维护滑动窗口值,Arrays.equals() 用作对比
class Solution { public List < Integer > findAnagrams ( String s, String p) { if ( s. length ( ) < p. length ( ) ) { return new ArrayList < > ( ) ; } int [ ] sCounts = new int [ 26 ] ; int [ ] pCounts = new int [ 26 ] ; List < Integer > ans = new ArrayList < > ( ) ; for ( int i = 0 ; i < p. length ( ) ; i++ ) { sCounts[ s. charAt ( i) - 'a' ] ++ ; pCounts[ p. charAt ( i) - 'a' ] ++ ; } if ( Arrays . equals ( sCounts, pCounts) ) { ans. add ( 0 ) ; } int left = 0 , right = p. length ( ) - 1 ; while ( right < s. length ( ) - 1 ) { sCounts[ s. charAt ( left++ ) - 'a' ] -- ; sCounts[ s. charAt ( ++ right) - 'a' ] ++ ; if ( Arrays . equals ( sCounts, pCounts) ) { ans. add ( left) ; } } return ans; }
}
三刷 - 每日一题
class Solution { public List < Integer > findAnagrams ( String s, String p) { if ( s. length ( ) < p. length ( ) ) return new ArrayList < > ( ) ; List < Integer > ans = new ArrayList < > ( ) ; int [ ] sCounts = new int [ 26 ] ; int [ ] pCounts = new int [ 26 ] ; for ( int i = 0 ; i < p. length ( ) ; i++ ) { sCounts[ s. charAt ( i) - 'a' ] ++ ; pCounts[ p. charAt ( i) - 'a' ] ++ ; } if ( Arrays . equals ( sCounts, pCounts) ) ans. add ( 0 ) ; int left = 0 , right = p. length ( ) - 1 ; while ( right < s. length ( ) - 1 ) { sCounts[ s. charAt ( left++ ) - 'a' ] -- ; sCounts[ s. charAt ( ++ right) - 'a' ] ++ ; if ( Arrays . equals ( sCounts, pCounts) ) ans. add ( left) ; } return ans; }
}