using
System;
using
System.Collections.Generic;
class
Program
{
public
static
string
RearrangeString(
string
s)
{
Dictionary<
char
,
int
> freqMap =
new
Dictionary<
char
,
int
>();
foreach
(
char
c
in
s)
{
if
(freqMap.ContainsKey(c))
freqMap++;
else
freqMap = 1;
}
PriorityQueue<Tuple<
int
,
char
>> maxHeap =
new
PriorityQueue<Tuple<
int
,
char
>>(
Comparer<Tuple<
int
,
char
>>.Create((a, b) => b.Item1.CompareTo(a.Item1)));
foreach
(
var
entry
in
freqMap)
{
maxHeap.Enqueue(Tuple.Create(-entry.Value, entry.Key));
}
List<
char
> res =
new
List<
char
>();
while
(maxHeap.Count > 0)
{
var
tuple1 = maxHeap.Dequeue();
int
freq1 = tuple1.Item1;
char
ch1 = tuple1.Item2;
if
(maxHeap.Count > 0)
{
var
tuple2 = maxHeap.Dequeue();
int
freq2 = tuple2.Item1;
char
ch2 = tuple2.Item2;
res.AddRange(
new
[] { ch1, ch2 });
freqMap[ch1]--;
freqMap[ch2]--;
if
(freqMap[ch1] > 0)
{
maxHeap.Enqueue(Tuple.Create(-freqMap[ch1], ch1));
}
if
(freqMap[ch2] > 0)
{
maxHeap.Enqueue(Tuple.Create(-freqMap[ch2], ch2));
}
}
else
if
(freq1 < -1)
{
return
"-1"
;
}
else
{
res.Add(ch1);
}
}
return
new
string
(res.ToArray());
}
static
void
Main()
{
string
s =
"aaabc"
;
Console.WriteLine(RearrangeString(s));
}
}
public
class
PriorityQueue<T>
{
private
List<T> heap;
private
readonly
IComparer<T> comparer;
public
int
Count => heap.Count;
public
PriorityQueue(IComparer<T> comparer =
null
)
{
this
.heap =
new
List<T>();
this
.comparer = comparer ?? Comparer<T>.Default;
}
public
void
Enqueue(T item)
{
heap.Add(item);
int
i = heap.Count - 1;
while
(i > 0)
{
int
parent = (i - 1) / 2;
if
(comparer.Compare(heap[parent], heap[i]) > 0)
break
;
Swap(parent, i);
i = parent;
}
}
public
T Dequeue()
{
int
lastIndex = heap.Count - 1;
if
(lastIndex < 0)
return
default
(T);
T frontItem = heap[0];
heap[0] = heap[lastIndex];
heap.RemoveAt(lastIndex);
lastIndex--;
int
i = 0;
while
(
true
)
{
int
leftChild = i * 2 + 1;
int
rightChild = i * 2 + 2;
if
(leftChild > lastIndex)
break
;
int
childToSwap = leftChild;
if
(rightChild <= lastIndex && comparer.Compare(heap[leftChild], heap[rightChild]) < 0)
childToSwap = rightChild;
if
(comparer.Compare(heap[i], heap[childToSwap]) < 0)
Swap(i, childToSwap);
else
break
;
i = childToSwap;
}
return
frontItem;
}
private
void
Swap(
int
i,
int
j)
{
T temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
}