11/30

算法
假设
n为字符串长度
maxnum为字符串中出现最多次的字符的出现次数
X字符为字符串中出现最多次的字符
以出现最多次的字符X为分隔
将其余各个字符插入X后方
每个X字符后插入一个字符,然后将下一个字符插入下一个X后
最后一个X字符插完,再回到第一个X字符后面再插入。
所以 除了最后一个X字符后可以为空,其他X字符后必须有至少一个字符。
所以只要(n + 1) / 2 >= maxnum则必定有解
可以将这种分隔抽象为堆
最后将堆合并即可
class Solution
{
public:
struct A
{
int num;
char ch;
} a[27];
static bool cmp(A a, A b)
{
if (a.num == b.num)
return a.ch < b.ch;
return a.num > b.num;
}
string reorganizeString(string S)
{
int maxnum = 0;
int n = S.size();
for (int i = 0; i <= 25; i++)
a[i].ch = 'a' + i;
for (int i = 0; i < n; i++)
maxnum = max(maxnum, ++a[S[i] - 'a'].num);
if ((n + 1) / 2 < maxnum)
return "";
string stack[maxnum];
sort(a, a + 25, cmp);
int charst = 1;
int charend = 0;
int stackst = 0;
for (int i = 1; i <= 25; i++)
{
if (a[i].num != 0)
charend = i;
else
break;
}
n -= maxnum;
while (n != 0)
{
while(a[charend].num==0)
charend--;
while (a[charst].num == 0)
{
charst++;
if (charst > charend)
{
charst = 1;
while (a[charst].num == 0)
charst++;
break;
}
}
a[charst].num--;
n--;
stack[stackst] += a[charst].ch;
if (stackst == maxnum - 1)
stackst = 0;
else
stackst++;
}
string ans;
for (int i = 0; i < maxnum; i++)
ans += a[0].ch + stack[i];
return ans;
}
};