Given a string s consisting of uppercase and lowercase English letters, rearrange its characters according to the following rules:
- All uppercase letters must appear in sorted (ascending lexicographical) order among themselves.
- All lowercase letters must appear in sorted (ascending lexicographical) order among themselves.
- The output string should alternate between uppercase and lowercase letters whenever both are available.
- If one category (uppercase or lowercase) is exhausted before the other, append all remaining characters of the other category to the end of the string in sorted order.
Return the resulting string.
Examples:
Input: s = "bAwutndekWEdkd"
Output: "AbEdWddekkntuw"
Explanation: The uppercase letters are A, E, W, which remain A, E, W after sorting. The lowercase letters become b, d, d, d, e, k, k, n, t, u, w after sorting. Alternate uppercase and lowercase while both are available to get AbEdWd. Once all uppercase letters are used, append the remaining lowercase letters in sorted order, resulting in AbEdWddekkntuw.Input: s = "AiBFR"
Output: "AiBFR"
Explanation: The uppercase letters are A, B, F, R, which are already sorted, and the lowercase letter is i. Alternating while both are available gives Ai. Since no lowercase letters remain, append the remaining uppercase letters in sorted order to obtain AiBFR.
Table of Content
[Naive Approach] Brute Force Approach - O(n * log n) Time and O(n) Space
Since the uppercase and lowercase letters need to be sorted independently, the idea is to first separate them into two different strings. After sorting both strings individually, we simply merge them by alternately picking one uppercase letter and one lowercase letter. If either group gets exhausted, append all remaining characters from the other group.
- Traverse the given string and store uppercase letters in one string and lowercase letters in another.
- Sort both strings in ascending lexicographical order.
- Initialize two pointers to traverse the sorted uppercase and lowercase strings.
- Alternately append one uppercase letter and one lowercase letter while both are available.
- Append the remaining characters from the non-empty string.
- Return the resulting string.
#include <bits/stdc++.h>
using namespace std;
string stringSort(string &s)
{
// Stores uppercase and lowercase letters separately
string upper = "", lower = "";
// Separate uppercase and lowercase characters
for (char ch : s)
{
if (isupper(ch))
upper += ch;
else
lower += ch;
}
// Sort both groups independently
sort(upper.begin(), upper.end());
sort(lower.begin(), lower.end());
string ans = "";
// Pointers for uppercase and lowercase strings
int i = 0, j = 0;
// Alternate between uppercase and lowercase letters
while (i < upper.size() && j < lower.size())
{
ans += upper[i++];
ans += lower[j++];
}
// Append remaining uppercase letters
while (i < upper.size())
ans += upper[i++];
// Append remaining lowercase letters
while (j < lower.size())
ans += lower[j++];
return ans;
}
int main()
{
string s = "bAwutndekWEdkd";
cout << stringSort(s) << endl;
return 0;
}
import java.util.*;
class GFG {
static String stringSort(String s)
{
// Stores uppercase and lowercase letters separately
StringBuilder upper = new StringBuilder();
StringBuilder lower = new StringBuilder();
// Separate uppercase and lowercase characters
for (char ch : s.toCharArray()) {
if (Character.isUpperCase(ch))
upper.append(ch);
else
lower.append(ch);
}
// Sort both groups independently
char[] upperArr = upper.toString().toCharArray();
char[] lowerArr = lower.toString().toCharArray();
Arrays.sort(upperArr);
Arrays.sort(lowerArr);
StringBuilder ans = new StringBuilder();
// Pointers for uppercase and lowercase strings
int i = 0, j = 0;
// Alternate between uppercase and lowercase letters
while (i < upperArr.length && j < lowerArr.length) {
ans.append(upperArr[i++]);
ans.append(lowerArr[j++]);
}
// Append remaining uppercase letters
while (i < upperArr.length)
ans.append(upperArr[i++]);
// Append remaining lowercase letters
while (j < lowerArr.length)
ans.append(lowerArr[j++]);
return ans.toString();
}
public static void main(String[] args)
{
String s = "bAwutndekWEdkd";
System.out.println(stringSort(s));
}
}
# Function to rearrange the string
def stringSort(s):
# Stores uppercase and lowercase letters separately
upper = []
lower = []
# Separate uppercase and lowercase characters
for ch in s:
if ch.isupper():
upper.append(ch)
else:
lower.append(ch)
# Sort both groups independently
upper.sort()
lower.sort()
ans = []
# Pointers for uppercase and lowercase lists
i = j = 0
# Alternate between uppercase and lowercase letters
while i < len(upper) and j < len(lower):
ans.append(upper[i])
i += 1
ans.append(lower[j])
j += 1
# Append remaining uppercase letters
while i < len(upper):
ans.append(upper[i])
i += 1
# Append remaining lowercase letters
while j < len(lower):
ans.append(lower[j])
j += 1
return "".join(ans)
# Driver code
if __name__ == "__main__":
s = "bAwutndekWEdkd"
print(stringSort(s))
using System;
class GFG {
// Function to rearrange the string
static string stringSort(string s)
{
// Stores uppercase and lowercase letters separately
string upper = "";
string lower = "";
// Separate uppercase and lowercase characters
foreach(char ch in s)
{
if (char.IsUpper(ch))
upper += ch;
else
lower += ch;
}
// Sort both groups independently
char[] upperArr = upper.ToCharArray();
char[] lowerArr = lower.ToCharArray();
Array.Sort(upperArr);
Array.Sort(lowerArr);
string ans = "";
// Pointers for uppercase and lowercase arrays
int i = 0, j = 0;
// Alternate between uppercase and lowercase letters
while (i < upperArr.Length && j < lowerArr.Length) {
ans += upperArr[i++];
ans += lowerArr[j++];
}
// Append remaining uppercase letters
while (i < upperArr.Length)
ans += upperArr[i++];
// Append remaining lowercase letters
while (j < lowerArr.Length)
ans += lowerArr[j++];
return ans;
}
static void Main()
{
string s = "bAwutndekWEdkd";
Console.WriteLine(stringSort(s));
}
}
// Function to rearrange the string
function stringSort(s)
{
// Stores uppercase and lowercase letters separately
let upper = [];
let lower = [];
// Separate uppercase and lowercase characters
for (const ch of s) {
if (ch >= "A" && ch <= "Z")
upper.push(ch);
else
lower.push(ch);
}
// Sort both groups independently
upper.sort();
lower.sort();
let ans = "";
// Pointers for uppercase and lowercase arrays
let i = 0, j = 0;
// Alternate between uppercase and lowercase letters
while (i < upper.length && j < lower.length) {
ans += upper[i++];
ans += lower[j++];
}
// Append remaining uppercase letters
while (i < upper.length)
ans += upper[i++];
// Append remaining lowercase letters
while (j < lower.length)
ans += lower[j++];
return ans;
}
// Driver code
let s = "bAwutndekWEdkd";
console.log(stringSort(s));
Output
AbEdWddekkntuw
[Expected Approach] Frequency Counting - O(n) Time and O(1) Space
The idea is to first count frequencies of lower case and upper case letters using two arrays of size 26. Then reconstruct the answer by alternately picking the smallest available uppercase and lowercase letters. If one category is exhausted, append the remaining characters of the other category in sorted order.
- Create two frequency arrays of size 26 to count uppercase and lowercase letters separately.
- Traverse the string and update the corresponding frequency array for each character.
- Maintain two pointers to track the current uppercase and lowercase characters.
- Alternately append the smallest available uppercase and lowercase characters, decreasing their frequencies after each use.
- Skip characters whose frequency becomes zero and continue until both frequency arrays are fully processed.
- Return the constructed string.
#include <bits/stdc++.h>
using namespace std;
// Function to rearrange the string
string stringSort(string &s)
{
// Stores the frequency of uppercase characters
int upper[26] = {0};
// Stores the frequency of lowercase characters
int lower[26] = {0};
// Count the frequency of each uppercase and lowercase character
for (char ch : s)
{
if (isupper(ch))
upper[ch - 'A']++;
else
lower[ch - 'a']++;
}
string ans = "";
// Pointers to the current uppercase and lowercase characters
int i = 0, j = 0;
// Alternate between uppercase and lowercase letters
while (i < 26 || j < 26)
{
// Find the next available uppercase character
while (i < 26 && upper[i] == 0)
i++;
// Append the uppercase character if available
if (i < 26)
{
ans += char('A' + i);
upper[i]--;
}
// Find the next available lowercase character
while (j < 26 && lower[j] == 0)
j++;
// Append the lowercase character if available
if (j < 26)
{
ans += char('a' + j);
lower[j]--;
}
}
return ans;
}
int main()
{
string s = "bAwutndekWEdkd";
cout << stringSort(s) << endl;
return 0;
}
import java.util.*;
class GFG {
// Function to rearrange the string
static String stringSort(String s)
{
// Stores the frequency of uppercase characters
int[] upper = new int[26];
// Stores the frequency of lowercase characters
int[] lower = new int[26];
// Count the frequency of each uppercase and
// lowercase character
for (char ch : s.toCharArray()) {
if (Character.isUpperCase(ch))
upper[ch - 'A']++;
else
lower[ch - 'a']++;
}
StringBuilder ans = new StringBuilder();
// Pointers to the current uppercase and lowercase
// characters
int i = 0, j = 0;
// Alternate between uppercase and lowercase letters
while (i < 26 || j < 26) {
// Find the next available uppercase character
while (i < 26 && upper[i] == 0)
i++;
// Append the uppercase character if available
if (i < 26) {
ans.append((char)('A' + i));
upper[i]--;
}
// Find the next available lowercase character
while (j < 26 && lower[j] == 0)
j++;
// Append the lowercase character if available
if (j < 26) {
ans.append((char)('a' + j));
lower[j]--;
}
}
return ans.toString();
}
public static void main(String[] args)
{
String s = "bAwutndekWEdkd";
System.out.println(stringSort(s));
}
}
# Function to rearrange the string
def stringSort(s):
# Stores the frequency of uppercase characters
upper = [0] * 26
# Stores the frequency of lowercase characters
lower = [0] * 26
# Count the frequency of each uppercase and lowercase character
for ch in s:
if ch.isupper():
upper[ord(ch) - ord('A')] += 1
else:
lower[ord(ch) - ord('a')] += 1
ans = []
# Pointers to the current uppercase and lowercase characters
i = j = 0
# Alternate between uppercase and lowercase letters
while i < 26 or j < 26:
# Find the next available uppercase character
while i < 26 and upper[i] == 0:
i += 1
# Append the uppercase character if available
if i < 26:
ans.append(chr(ord('A') + i))
upper[i] -= 1
# Find the next available lowercase character
while j < 26 and lower[j] == 0:
j += 1
# Append the lowercase character if available
if j < 26:
ans.append(chr(ord('a') + j))
lower[j] -= 1
return "".join(ans)
# Driver code
if __name__ == "__main__":
s = "bAwutndekWEdkd"
print(stringSort(s))
using System;
class GFG {
// Function to rearrange the string
static string stringSort(string s)
{
// Stores the frequency of uppercase characters
int[] upper = new int[26];
// Stores the frequency of lowercase characters
int[] lower = new int[26];
// Count the frequency of each uppercase and
// lowercase character
foreach(char ch in s)
{
if (char.IsUpper(ch))
upper[ch - 'A']++;
else
lower[ch - 'a']++;
}
string ans = "";
// Pointers to the current uppercase and lowercase
// characters
int i = 0, j = 0;
// Alternate between uppercase and lowercase letters
while (i < 26 || j < 26) {
// Find the next available uppercase character
while (i < 26 && upper[i] == 0)
i++;
// Append the uppercase character if available
if (i < 26) {
ans += (char)('A' + i);
upper[i]--;
}
// Find the next available lowercase character
while (j < 26 && lower[j] == 0)
j++;
// Append the lowercase character if available
if (j < 26) {
ans += (char)('a' + j);
lower[j]--;
}
}
return ans;
}
static void Main()
{
string s = "bAwutndekWEdkd";
Console.WriteLine(stringSort(s));
}
}
// Function to rearrange the string
function stringSort(s)
{
// Stores the frequency of uppercase characters
const upper = new Array(26).fill(0);
// Stores the frequency of lowercase characters
const lower = new Array(26).fill(0);
// Count the frequency of each uppercase and lowercase
// character
for (const ch of s) {
if (ch >= "A" && ch <= "Z")
upper[ch.charCodeAt(0) - "A".charCodeAt(0)]++;
else
lower[ch.charCodeAt(0) - "a".charCodeAt(0)]++;
}
let ans = "";
// Pointers to the current uppercase and lowercase
// characters
let i = 0, j = 0;
// Alternate between uppercase and lowercase letters
while (i < 26 || j < 26) {
// Find the next available uppercase character
while (i < 26 && upper[i] === 0)
i++;
// Append the uppercase character if available
if (i < 26) {
ans += String.fromCharCode("A".charCodeAt(0)
+ i);
upper[i]--;
}
// Find the next available lowercase character
while (j < 26 && lower[j] === 0)
j++;
// Append the lowercase character if available
if (j < 26) {
ans += String.fromCharCode("a".charCodeAt(0)
+ j);
lower[j]--;
}
}
return ans;
}
// Driver code
const s = "bAwutndekWEdkd";
console.log(stringSort(s));
Output
AbEdWddekkntuw