给定一个字符串和一个正整数d。在给定的字符串某些字符可能会重复。重新排列给定字符串的字符,以使相同字符彼此相距d距离。请注意,可能存在许多可能的重排,输出应该是可能的重排之一。如果没有这样的安排,也应报告。
预期的时间复杂度为O(n),其中n是输入字符串的长度。
例子:
Input: "abb", d = 2
Output: "bab"
Input: "aacbbc", d = 3
Output: "abcabc"
Input: "geeksforgeeks", d = 3
Output: egkegkesfesor
Input: "aaa", d = 2
Output: Cannot be rearranged
解决此问题的方法是对所有字符的频率进行计数,并首先考虑最频繁出现的字符,并将所有出现的字符尽可能地靠近。放置最频繁的字符后,对其余字符重复相同的过程。
- 令给定的字符串为str,字符串的大小为n
- 遍历str,将所有字符及其频率存储在Max Heap MH(使用优先级队列实现)中。频率值决定了MH的顺序,即,最频繁出现的字符位于MH的根部。
- 将str的所有字符设置为“ \ 0”。
- 当MH不为空时,请执行以下操作。
- 提取最常见的字符。令提取的字符为x,其频率为f。
- 在str中找到第一个可用位置,即在str中找到第一个’\ 0’。
- 设第一个位置为p。在p,p + d,.. p +(f-1)d处填充x
下面是上述算法的实现。
C
// C program to rearrange a string so that all same
// characters become at least d distance away
#include
#include
#include
#define MAX 256
// A structure to store a character 'c' and its frequency
// 'f' in input string
typedef struct charFreq {
char c;
int f;
} charFreq ;
// A utility function to swap two charFreq items.
void swap(charFreq* x, charFreq* y)
{
charFreq z = *x;
*x = *y;
*y = z;
}
// A utility function to maxheapify the node freq[i] of a
// heap stored in freq[]
void maxHeapify(charFreq freq[], int i, int heap_size)
{
int l = i * 2 + 1;
int r = i * 2 + 2;
int largest = i;
if (l < heap_size && freq[l].f > freq[i].f)
largest = l;
if (r < heap_size && freq[r].f > freq[largest].f)
largest = r;
if (largest != i) {
swap(&freq[i], &freq[largest]);
maxHeapify(freq, largest, heap_size);
}
}
// A utility function to convert the array freq[] to a max
// heap
void buildHeap(charFreq freq[], int n)
{
int i = (n - 1) / 2;
while (i >= 0) {
maxHeapify(freq, i, n);
i--;
}
}
// A utility function to remove the max item or root from
// max heap
charFreq extractMax(charFreq freq[], int heap_size)
{
charFreq root = freq[0];
if (heap_size > 1) {
freq[0] = freq[heap_size - 1];
maxHeapify(freq, 0, heap_size - 1);
}
return root;
}
// The main function that rearranges input string 'str' such
// that two same characters become d distance away
void rearrange(char str[], int d)
{
// Find length of input string
int n = strlen(str);
// Create an array to store all characters and their
// frequencies in str[]
charFreq freq[MAX] = { { 0, 0 } };
int m = 0; // To store count of distinct characters in
// str[]
// Traverse the input string and store frequencies of
// all characters in freq[] array.
for (int i = 0; i < n; i++) {
char x = str[i];
// If this character has occurred first time,
// increment m
if (freq[x].c == 0)
freq[x].c = x, m++;
(freq[x].f)++;
str[i] = '\0'; // This change is used later
}
// Build a max heap of all characters
buildHeap(freq, MAX);
// Now one by one extract all distinct characters from
// max heap and put them back in str[] with the d
// distance constraint
for (int i = 0; i < m; i++) {
charFreq x = extractMax(freq, MAX - i);
// Find the first available position in str[]
int p = i;
while (str[p] != '\0')
p++;
// Fill x.c at p, p+d, p+2d, .. p+(f-1)d
for (int k = 0; k < x.f; k++) {
// If the index goes beyond size, then string
// cannot be rearranged.
if (p + d * k >= n) {
printf("Cannot be rearranged");
exit(0);
}
str[p + d * k] = x.c;
}
}
}
// Driver Code
int main()
{
char str[] = "aabbcc";
// Function Call
rearrange(str, 3);
printf("%s",str);
}
C++
// C++ program to rearrange a string so that all same
// characters become at least d distance away using STL
#include
#include
using namespace std;
typedef pair PAIR;
// Comparator of priority_queue
struct cmp {
bool operator()(const PAIR& a, const PAIR& b)
{
if(a.second < b.second) return true;
else if(a.second > b.second) return false;
else return a.first > b.first;
}
};
void rearrange(char* str, int d)
{
// Length of the string
int n = strlen(str);
// A structure to store a character and its frequency
unordered_map m;
// Traverse the input string and store frequencies of
// all characters.
for (int i = 0; i < n; i++) {
m[str[i]]++;
str[i] = '\0';
}
// max-heap
priority_queue, cmp> pq(m.begin(),
m.end());
// Now one by one extract all distinct characters from
// heap and put them back in str[] with the d
// distance constraint
while (pq.empty() == false) {
char x = pq.top().first;
// Find the first available position in str[]
int p = 0;
while (str[p] != '\0')
p++;
// Fill x at p, p+d, p+2d, .. p+(frequency-1)d
for (int k = 0; k < pq.top().second; k++) {
// If the index goes beyond size, then string
// cannot be rearranged.
if (p + d * k >= n) {
cout << "Cannot be rearranged";
exit(0);
}
str[p + d * k] = x;
}
pq.pop();
}
}
// Driver Code
int main()
{
char str[] = "aabbcc";
// Function call
rearrange(str, 3);
cout << str;
}
Python 3
# Python program to rearrange a string so that all same
# characters become at least d distance away
MAX = 256
# A structure to store a character 'c' and its frequency 'f'
# in input string
class charFreq(object):
def __init__(self, c, f):
self.c = c
self.f = f
# A utility function to swap two charFreq items.
def swap(x, y):
return y, x
# A utility function
def toList(string):
t = []
for x in string:
t.append(x)
return t
# A utility function
def toString(l):
return ''.join(l)
# A utility function to maxheapify the node freq[i] of a heap
# stored in freq[]
def maxHeapify(freq, i, heap_size):
l = i*2 + 1
r = i*2 + 2
largest = i
if l < heap_size and freq[l].f > freq[i].f:
largest = l
if r < heap_size and freq[r].f > freq[largest].f:
largest = r
if largest != i:
freq[i], freq[largest] = swap(freq[i], freq[largest])
maxHeapify(freq, largest, heap_size)
# A utility function to convert the array freq[] to a max heap
def buildHeap(freq, n):
i = (n - 1)//2
while i >= 0:
maxHeapify(freq, i, n)
i -= 1
# A utility function to remove the max item or root from max heap
def extractMax(freq, heap_size):
root = freq[0]
if heap_size > 1:
freq[0] = freq[heap_size-1]
maxHeapify(freq, 0, heap_size-1)
return root
# The main function that rearranges input string 'str' such that
# two same characters become d distance away
def rearrange(string, d):
# Find length of input string
n = len(string)
# Create an array to store all characters and their
# frequencies in str[]
freq = []
for x in range(MAX):
freq.append(charFreq(0, 0))
m = 0
# Traverse the input string and store frequencies of all
# characters in freq[] array.
for i in range(n):
x = ord(string[i])
# If this character has occurred first time, increment m
if freq[x].c == 0:
freq[x].c = chr(x)
m += 1
freq[x].f += 1
string[i] = '\0'
# Build a max heap of all characters
buildHeap(freq, MAX)
# Now one by one extract all distinct characters from max heap
# and put them back in str[] with the d distance constraint
for i in range(m):
x = extractMax(freq, MAX-i)
# Find the first available position in str[]
p = i
while string[p] != '\0':
p += 1
# Fill x.c at p, p+d, p+2d, .. p+(f-1)d
for k in range(x.f):
# If the index goes beyond size, then string cannot
# be rearranged.
if p + d*k >= n:
print ("Cannot be rearranged")
return
string[p + d*k] = x.c
return toString(string)
# Driver program
string = "aabbcc"
print (rearrange(toList(string), 3))
# This code is contributed by BHAVYA JAIN
输出
abcabc