public class Solution {int nextindex = 0;public IList<int> FindAnagrams(string s, string p) { List<int> list = new List<int>(); if (s == null || s.Length == 0 || p == null || p.Length == 0) return list; int[] hash = new int[256]; //character hash //record each character in p to hash foreach (char c in p) { hash[c]++; } //two points, initialize count to p's length int left = 0, right = 0, count = p.Length; while (right < s.Length) { //move right everytime, if the character exists in p's hash, decrease the count //current hash value >= 1 means the character is existing in p if (hash[s[right++]]-- >= 1) count--; //when the count is down to 0, means we found the right anagram //then add window's left to result list if (count == 0) list.Add(left); //if we find the window's size equals to p, then we have to move left (narrow the window) to find the new match window //++ to reset the hash because we kicked out the left //only increase the count if the character is in p //the count >= 0 indicate it was original in the hash, cuz it won't go below 0 if (right - left == p.Length && hash[s[left++]]++ >= 0) count++; } return list; } }
https://leetcode.com/problems/find-all-anagrams-in-a-string/#/description
上面的是别人在讨论区的实现。
下面是我自己的实现,使用非递归方法,性能更好:
1 public class Solution 2 { 3 public IList<int> FindAnagrams(string s, string p) 4 { 5 var list = new List<int>(); 6 var dicp = new Dictionary<char, int>(); 7 foreach (var c in p) 8 { 9 if (dicp.ContainsKey(c)) 10 { 11 dicp[c]++; 12 } 13 else 14 { 15 dicp.Add(c, 1); 16 } 17 } 18 var dictemp = new Dictionary<char, int>(dicp); 19 var counttemp = p.Length; 20 var beginindex = 0; 21 for (var i = 0; i < s.Length; i++) 22 { 23 var c = s[i]; 24 if (dictemp.ContainsKey(c)) 25 { 26 if (dictemp[c] > 0) 27 { 28 dictemp[c]--; 29 counttemp--; 30 if (counttemp == 0) 31 { 32 list.Add(beginindex); 33 34 //restore status 35 dictemp[s[beginindex]]++; 36 beginindex = beginindex + 1; 37 counttemp++; 38 } 39 } 40 else 41 { 42 if (s[beginindex] == c) 43 { 44 beginindex = beginindex + 1; 45 } 46 else 47 { 48 beginindex = i; 49 dictemp = new Dictionary<char, int>(dicp); 50 dictemp[c]--; 51 counttemp = p.Length - 1; 52 } 53 } 54 } 55 else 56 { 57 beginindex = i + 1; 58 dictemp = new Dictionary<char, int>(dicp); 59 counttemp = p.Length; 60 } 61 } 62 return list; 63 } 64 }