【LeetCode 49】字母异位词分组
作者:互联网
比较复杂的方法。
public static List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> list = new ArrayList<List<String>>();
int n = strs.length;
if (n == 0)
return null;
int[] pointers = new int[n+1];
Arrays.fill(pointers, -2);
int i = 0;
int j = i+1;
int k = 1; // the position in pointers
pointers[0] = -1;
while (i < n)
{
while (j < n) // 相邻两个字符串的等价情况
{
if (isAnagram(strs[i], strs[j]))
{
i++;
j++;
}
else
break;
}
while (j < n && !isAnagram(strs[i], strs[j])) // 寻找不相邻字符串的等价情况
j++;
if (j < n) // 使得其相邻
{
exchange(strs, i+1, j);
i++;
//j++;
}
if (j == n)
{
pointers[k++] = i;
i++;
j = i+1;
}
}
int p = 0; // position in pointer array
int t = 0;
while (p + 1 <= n && pointers[p] != -2)
{
List<String> ret = new ArrayList<String>();
// pointers[p]+1 到 pointers[p+1]是一个区间的位置
// p+1应该位于pointers数组之中
for (t = pointers[p]+1; t <= pointers[p+1]; t++)
{
ret.add(strs[t]);
}
if (!ret.isEmpty())
list.add(ret);
p++;
}
return list;
}
private static void exchange(String[] strs, int i, int j)
{
String tmp = strs[i];
strs[i] = strs[j];
strs[j] = tmp;
}
private static boolean isAnagram(String s1, String s2) // O(n)
{
boolean ret = false;
int n1 = s1.length();
int n2 = s2.length();
if (n1 != n2)
return ret;
Map<Character, Integer> charMap = new HashMap<Character, Integer>();
for (int i = 0; i < n1; i++)
{
char c = s1.charAt(i);
if (charMap.containsKey(c))
charMap.put(c, charMap.get(c)+1);
else
charMap.put(c, 1);
}
for (int i = 0; i < n2; i++)
{
char c = s2.charAt(i);
if (!charMap.containsKey(c))
return ret;
if (charMap.containsKey(c) && charMap.get(c) > 0)
{
charMap.put(c, charMap.get(c)-1);
if (charMap.get(c) == 0)
charMap.remove(c);
}
}
if (charMap.isEmpty())
ret = true;
return ret;
}
标签:charMap,49,int,异位,pointers,++,ret,strs,LeetCode 来源: https://blog.csdn.net/juttajry/article/details/122255645