Valid Word Abbreviation — Easy Problem & Solution
An abbreviation replaces any number of non-adjacent, non-empty substrings of a word with their lengths.
- Difficulty: Easy
- Topics: Strings, Two Pointers
- Asked at: Amazon, Google, Meta
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
An abbreviation replaces any number of non-adjacent, non-empty substrings of a word with their lengths. For example "codekairo" can be abbreviated as "c7o" or "co5ro", but not "c1de5" — 1 and the following letters would come from adjacent replacements written separately.
A number in the abbreviation must not have a leading zero.
Given word and abbr, return true if abbr is a valid abbreviation of word.
Example 1
Input: word = "codekairo", abbr = "c7o"
Output: true
Explanation: c, then 7 letters skipped, then o.
Example 2
Input: word = "codekairo", abbr = "c07o"
Output: false
Explanation: A leading zero is never allowed.
Example 3
Input: word = "apple", abbr = "a2e"
Output: false
Explanation: a2e covers only 4 characters; apple has 5.
Constraints
1 <= word.length <= 201 <= abbr.length <= 10word consists of lowercase letters.abbr consists of lowercase letters and digits.
How to solve Valid Word Abbreviation
Walk both strings with independent pointers. A letter in abbr must match the current letter of word; a digit run is an instruction to skip that many characters of word.
Approach
- While both pointers are in range: if
abbr[j]is a digit, reject a leading'0', then parse the full number and advanceiby it. - Otherwise compare
word[i]withabbr[j]and advance both on a match, rejecting on a mismatch. - Return
trueonly when both pointers have reached the end.
Why it works
Parsing the entire digit run at once is what enforces the 'non-adjacent' rule: two adjacent replacements would have to be written as one number, so any well-formed abbreviation has letters between its numbers. Requiring both pointers to land exactly at the end rejects abbreviations that cover too little or skip past the end.
Complexity
- Time —
O(n) - Space —
O(1)
Pitfalls
- Skipping the leading-zero check accepts
"c07o". - Returning
truewhen onlyihas reached the end leaves unconsumed abbreviation characters. ican overshootword.lengthafter a jump — the final equality check must be exact, not>=.
Reference solution
Python
def validWordAbbreviation(word: str, abbr: str) -> bool:
i = j = 0
while i < len(word) and j < len(abbr):
if abbr[j].isdigit():
if abbr[j] == "0":
return False
num = 0
while j < len(abbr) and abbr[j].isdigit():
num = num * 10 + int(abbr[j])
j += 1
i += num
else:
if word[i] != abbr[j]:
return False
i += 1
j += 1
return i == len(word) and j == len(abbr)JavaScript
var validWordAbbreviation = function(word, abbr) {
var i = 0, j = 0;
while (i < word.length && j < abbr.length) {
var c = abbr.charAt(j);
if (c >= "0" && c <= "9") {
if (c === "0") return false;
var num = 0;
while (j < abbr.length && abbr.charAt(j) >= "0" && abbr.charAt(j) <= "9") {
num = num * 10 + (abbr.charCodeAt(j) - 48);
j++;
}
i += num;
} else {
if (word.charAt(i) !== c) return false;
i++;
j++;
}
}
return i === word.length && j === abbr.length;
};Also on the editorial tab: C, C#, C++, Go, Java, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.