Given a string sthat consists of only alphanumeric characters and dashes. The string is separated into n+1 groups by n dashes. We are also given a number k, the task is to reformat the string s, such that each group contains exactly k characters, except for the first group, which could be shorter than k but still must contain at least one character. Furthermore, a dash must be inserted between two groups, and you should convert all lowercase letters to uppercase. Return the reformatted string.
Examples:
Input: s = "ab-c1-23-xYz", k = 3
Output: "ABC-123-XYZ"
Explanation: After removing dashes and converting lowercase letters to uppercase: "ABC123XYZ"Input: s = "7h-8K-lm-9", k = 2
Output: "7-H8-KL-M9"
Explanation: After removing dashes and converting lowercase letters to uppercase: "7H8KLM9", Now divide into groups of size 2 from the end: "7-H8-KL-M9", The first group contains only 1 character, which is allowed.
Table of Content
[Naive Approach] Cleaning String + Inserting Dashes – O(n) Time and O(n) Space
The idea is to first remove all dashes from the string and convert every character to uppercase. After obtaining the cleaned string, dashes are inserted starting from the end after every group of
kcharacters. Processing from the back ensures that the first group may contain fewer thankcharacters while all remaining groups contain exactlykcharacters.
- Traverse the string: Ignore dashes, Convert characters to uppercase and Store them in a new string
- Starting from the end: Insert a dash after every
kcharacters - Return the formatted string
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
string reFormatString(string &s, int k) {
// Remove all dashes and convert to uppercase
string cleaned;
for (char c : s) {
if (c != '-') {
cleaned.push_back(toupper(c));
}
}
// If string is empty, return empty string
if (cleaned.empty()) return "";
// Insert dashes from the end
int i = cleaned.length() - k;
while (i > 0) {
cleaned.insert(i, "-");
i = i - k;
}
return cleaned;
}
int main() {
string s = "5F3Z-2e-9-w";
int k = 4;
cout << reFormatString(s, k) << endl;
return 0;
}
// Java program to reformat string by adding dashes from the end
import java.util.*;
class GfG {
static String reFormatString(String s, int k) {
// Remove all dashes and convert to uppercase
StringBuilder cleaned = new StringBuilder();
for (char c : s.toCharArray()) {
if (c != '-') {
cleaned.append(Character.toUpperCase(c));
}
}
// If string is empty, return empty string
if (cleaned.length() == 0) return "";
// Insert dashes from the end
int i = cleaned.length() - k;
while (i > 0) {
cleaned.insert(i, "-");
i = i - k;
}
return cleaned.toString();
}
public static void main(String[] args) {
String s = "5F3Z-2e-9-w";
int k = 4;
System.out.println(reFormatString(s, k));
}
}
# Python program to reformat string by adding dashes from the end
def reFormatString(s, k):
# Remove all dashes and convert to uppercase
cleaned = []
for ch in s:
if ch != '-':
cleaned.append(ch.upper())
cleaned = ''.join(cleaned)
# If string is empty, return empty string
if not cleaned:
return ""
# Insert dashes from the end
result = list(cleaned)
i = len(cleaned) - k
while i > 0:
result.insert(i, '-')
i -= k
return ''.join(result)
# Driver code
if __name__ == "__main__":
s = "5F3Z-2e-9-w"
k = 4
print(reFormatString(s, k))
// C# program to reformat string by adding dashes from the end
using System;
using System.Text;
class GfG {
static string reFormatString(string s, int k) {
// Remove all dashes and convert to uppercase
StringBuilder cleaned = new StringBuilder();
foreach (char c in s) {
if (c != '-') {
cleaned.Append(char.ToUpper(c));
}
}
// If string is empty, return empty string
if (cleaned.Length == 0) return "";
// Insert dashes from the end
int i = cleaned.Length - k;
while (i > 0) {
cleaned.Insert(i, "-");
i = i - k;
}
return cleaned.ToString();
}
static void Main(string[] args) {
string s = "5F3Z-2e-9-w";
int k = 4;
Console.WriteLine(reFormatString(s, k));
}
}
// JavaScript program to reformat string by adding dashes from the end
function reFormatString(s, k) {
// Remove all dashes and convert to uppercase
let cleaned = "";
for (let ch of s) {
if (ch !== '-') {
cleaned += ch.toUpperCase();
}
}
// If string is empty, return empty string
if (cleaned.length === 0) return "";
// Insert dashes from the end
let result = cleaned.split('');
let i = cleaned.length - k;
while (i > 0) {
result.splice(i, 0, '-');
i -= k;
}
return result.join('');
}
// Driver code
const s = "5F3Z-2e-9-w";
const k = 4;
console.log(reFormatString(s, k));
Output
5F3Z-2E9W
[Space Optimized Approach] Using In-Place Processing – O(n) Time and O(1) Extra Space
The idea is to reuse the original string instead of creating another cleaned string separately. All dashes are removed and characters are converted to uppercase directly inside the same string by shifting valid characters toward the end. Then the formatted license key is constructed by traversing backward and inserting dashes after every
kcharacters.
- Traverse the string from right to left
- Remove dashes and overwrite characters in-place
- Convert characters to uppercase while shifting
- Extract the cleaned portion of the string
- Build the final formatted string from back by inserting dashes after every
kcharacters - Reverse the result before returning it
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string reFormatString(string &s, int k)
{
int n = s.size();
int write = n - 1;
// Remove dashes and convert to uppercase
for (int i = n - 1; i >= 0; i--) {
if (s[i] != '-') {
s[write--] = toupper(s[i]);
}
}
int chars = n - write - 1;
// Extract cleaned string
string temp = s.substr(write + 1, chars);
string ans;
int cnt = 0;
// Build answer from back
for (int i = chars - 1; i >= 0; i--) {
ans += temp[i];
cnt++;
if (cnt == k && i != 0) {
ans += '-';
cnt = 0;
}
}
reverse(ans.begin(), ans.end());
return ans;
}
int main()
{
string s = "5F3Z-2e-9-w";
int k = 4;
cout << reFormatString(s, k);
return 0;
}
import java.util.*;
class GFG {
static String reFormatString(StringBuilder s, int k)
{
int n = s.length();
int write = n - 1;
// Remove dashes and convert to uppercase
for (int i = n - 1; i >= 0; i--) {
if (s.charAt(i) != '-') {
s.setCharAt(write--,
Character.toUpperCase(s.charAt(i)));
}
}
int chars = n - write - 1;
// Extract cleaned string
String temp = s.substring(write + 1, write + 1 + chars);
StringBuilder ans = new StringBuilder();
int cnt = 0;
// Build answer from back
for (int i = chars - 1; i >= 0; i--) {
ans.append(temp.charAt(i));
cnt++;
if (cnt == k && i != 0) {
ans.append('-');
cnt = 0;
}
}
return ans.reverse().toString();
}
public static void main(String[] args)
{
StringBuilder s = new StringBuilder("5F3Z-2e-9-w");
int k = 4;
System.out.println(reFormatString(s, k));
}
}
def reFormatString(s, k):
s = list(s)
n = len(s)
write = n - 1
# Remove dashes and convert to uppercase
for i in range(n - 1, -1, -1):
if s[i] != '-':
s[write] = s[i].upper()
write -= 1
chars = n - write - 1
# Extract cleaned string
temp = ''.join(s[write + 1: write + 1 + chars])
ans = ""
cnt = 0
# Build answer from back
for i in range(chars - 1, -1, -1):
ans += temp[i]
cnt += 1
if cnt == k and i != 0:
ans += '-'
cnt = 0
return ans[::-1]
s = "5F3Z-2e-9-w"
k = 4
print(reFormatString(s, k))
using System;
using System.Text;
class GFG {
static string reFormatString(StringBuilder s, int k)
{
int n = s.Length;
int write = n - 1;
// Remove dashes and convert to uppercase
for (int i = n - 1; i >= 0; i--) {
if (s[i] != '-') {
s[write--] = Char.ToUpper(s[i]);
}
}
int chars = n - write - 1;
// Extract cleaned string
string temp = s.ToString(write + 1, chars);
StringBuilder ans = new StringBuilder();
int cnt = 0;
// Build answer from back
for (int i = chars - 1; i >= 0; i--) {
ans.Append(temp[i]);
cnt++;
if (cnt == k && i != 0) {
ans.Append('-');
cnt = 0;
}
}
char[] arr = ans.ToString().ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
static void Main()
{
StringBuilder s = new StringBuilder("5F3Z-2e-9-w");
int k = 4;
Console.WriteLine(reFormatString(s, k));
}
}
function reFormatString(s, k)
{
s = s.split('');
let n = s.length;
let write = n - 1;
// Remove dashes and convert to uppercase
for (let i = n - 1; i >= 0; i--) {
if (s[i] !== '-') {
s[write--] = s[i].toUpperCase();
}
}
let chars = n - write - 1;
// Extract cleaned string
let temp = s.slice(write + 1, write + 1 + chars).join('');
let ans = "";
let cnt = 0;
// Build answer from back
for (let i = chars - 1; i >= 0; i--) {
ans += temp[i];
cnt++;
if (cnt === k && i !== 0) {
ans += '-';
cnt = 0;
}
}
return ans.split('').reverse().join('');
}
let s = "5F3Z-2e-9-w";
let k = 4;
console.log(reFormatString(s, k));
Output
5F3Z-2E9W