解题思路:1.先统计每个字母出现的次数 2. 按照次数由高到底排序 3. 先取最高,假设是a 4. 然后从次高中取
一个,组合起来,然后重新统计次数然后回到3。
public String reorganizeString(String S)
{
int n = S.length();
// 键:字符,值:下标
HashMap<Character, Integer> map = new HashMap<>();
// 统计每个字符的出现次数
for (int i=0; i<n; i++)
{
if (!map.containsKey(S.charAt(i)))
{
map.put(S.charAt(i), 1);
}
else
{
map.put(S.charAt(i), map.get(S.charAt(i))+1);
}
}
ArrayList<Map.Entry<Character, Integer>> arrayList = new ArrayList<Map.Entry<Character, Integer>>(map.entrySet());
// 根据value的大小,对Entry对象进行排序
sortMap(arrayList);
int max = arrayList.get(0).getValue(); // 出现最多的出现次数
char maxi = arrayList.get(0).getKey(); // 出现次数最多的字符
// 如果其他字符的出现次数+1 小于出现次数最多的字符的出现次数,则无法重构
if (n-max+1 < max)
{
return "";
}
// 重构字符串
StringBuilder sBuilder = new StringBuilder();
while (arrayList.size() > 1)
{
// 从最高字符中取一个
Entry<Character, Integer> entry = arrayList.get(0);
sBuilder.append(entry.getKey());
entry.setValue(entry.getValue()-1);
// 当前字符被用完
if (entry.getValue() == 0)
{
arrayList.remove(entry);
}
if (arrayList.size() <= 1)
break;
// 从次高字符中取一个
entry = arrayList.get(1);
sBuilder.append(entry.getKey());
entry.setValue(entry.getValue()-1);
// 当前字符被用完
if (entry.getValue() == 0)
{
arrayList.remove(entry);
}
// 重新排序(这里很重要)
sortMap(arrayList);
}
// 处理arrayList中最后一个元素
sBuilder.append(arrayList.get(arrayList.size()-1).getKey());
return sBuilder.toString(); // aaa bbb ccc abababccc
}
void sortMap(ArrayList<Map.Entry<Character, Integer>> arrayList)
{
// 根据value的大小,对Entry对象进行排序
Collections.sort(arrayList, new Comparator<Map.Entry<Character, Integer>>()
{
@Override
public int compare(Entry<Character, Integer> e1, Entry<Character, Integer> e2)
{
return e2.getValue().compareTo(e1.getValue());
}
});
}