Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Build confidence with an intuition-first walkthrough focused on core interview patterns fundamentals.
You are given a license key represented as a string s that consists of only alphanumeric characters and dashes. The string is separated into n + 1 groups by n dashes. You are also given an integer k.
We want 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, there must be a dash inserted between two groups, and you should convert all lowercase letters to uppercase.
Return the reformatted license key.
Example 1:
Input: s = "5F3Z-2e-9-w", k = 4 Output: "5F3Z-2E9W" Explanation: The string s has been split into two parts, each part has 4 characters. Note that the two extra dashes are not needed and can be removed.
Example 2:
Input: s = "2-5g-3-J", k = 2 Output: "2-5G-3J" Explanation: The string s has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above.
Constraints:
1 <= s.length <= 105s consists of English letters, digits, and dashes '-'.1 <= k <= 104Problem summary: You are given a license key represented as a string s that consists of only alphanumeric characters and dashes. The string is separated into n + 1 groups by n dashes. You are also given an integer k. We want 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, there must be a dash inserted between two groups, and you should convert all lowercase letters to uppercase. Return the reformatted license key.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: General problem-solving
"5F3Z-2e-9-w" 4
"2-5g-3-J" 2
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #482: License Key Formatting
class Solution {
public String licenseKeyFormatting(String s, int k) {
int n = s.length();
int cnt = (int) (n - s.chars().filter(ch -> ch == '-').count()) % k;
if (cnt == 0) {
cnt = k;
}
StringBuilder ans = new StringBuilder();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
if (c == '-') {
continue;
}
ans.append(Character.toUpperCase(c));
--cnt;
if (cnt == 0) {
cnt = k;
if (i != n - 1) {
ans.append('-');
}
}
}
if (ans.length() > 0 && ans.charAt(ans.length() - 1) == '-') {
ans.deleteCharAt(ans.length() - 1);
}
return ans.toString();
}
}
// Accepted solution for LeetCode #482: License Key Formatting
func licenseKeyFormatting(s string, k int) string {
n := len(s)
cnt := (n - strings.Count(s, "-")) % k
if cnt == 0 {
cnt = k
}
var ans strings.Builder
for i := 0; i < n; i++ {
c := s[i]
if c == '-' {
continue
}
if cnt == 0 {
cnt = k
ans.WriteByte('-')
}
ans.WriteRune(unicode.ToUpper(rune(c)))
cnt--
}
return ans.String()
}
# Accepted solution for LeetCode #482: License Key Formatting
class Solution:
def licenseKeyFormatting(self, s: str, k: int) -> str:
n = len(s)
cnt = (n - s.count("-")) % k or k
ans = []
for i, c in enumerate(s):
if c == "-":
continue
ans.append(c.upper())
cnt -= 1
if cnt == 0:
cnt = k
if i != n - 1:
ans.append("-")
return "".join(ans).rstrip("-")
// Accepted solution for LeetCode #482: License Key Formatting
struct Solution;
impl Solution {
fn license_key_formatting(s: String, k: i32) -> String {
let mut res: Vec<char> = vec![];
let mut i = 0;
for c in s.chars().rev() {
if c != '-' {
res.push(c);
i += 1;
if i == k {
i = 0;
res.push('-');
}
}
}
if let Some(&'-') = res.last() {
res.pop();
}
res.iter().rev().collect::<String>().to_ascii_uppercase()
}
}
#[test]
fn test() {
let s = "5F3Z-2e-9-w".to_string();
let k = 4;
let o = "5F3Z-2E9W".to_string();
assert_eq!(Solution::license_key_formatting(s, k), o);
let s = "2-5g-3-J".to_string();
let k = 2;
let o = "2-5G-3J".to_string();
assert_eq!(Solution::license_key_formatting(s, k), o);
}
// Accepted solution for LeetCode #482: License Key Formatting
function licenseKeyFormatting(s: string, k: number): string {
const n = s.length;
let cnt = (n - (s.match(/-/g) || []).length) % k || k;
const ans: string[] = [];
for (let i = 0; i < n; i++) {
const c = s[i];
if (c === '-') {
continue;
}
ans.push(c.toUpperCase());
if (--cnt === 0) {
cnt = k;
if (i !== n - 1) {
ans.push('-');
}
}
}
while (ans.at(-1) === '-') {
ans.pop();
}
return ans.join('');
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.