Skip to content

Commit 9bab1bb

Browse files
author
FreeTymeKiyan
committed
Add 408 Valid Word Abbreviation with unit tests
1 parent 275e69b commit 9bab1bb

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.freetymekiyan.algorithms.level.easy;
2+
3+
/**
4+
* 408. Valid Word Abbreviation
5+
* <p>
6+
* Given a non-empty string s and an abbreviation abbr, return whether the string matches with the given abbreviation.
7+
* <p>
8+
* A string such as "word" contains only the following valid abbreviations:
9+
* <p>
10+
* ["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]
11+
* <p>
12+
* Notice that only the above abbreviations are valid abbreviations of the string "word". Any other string is not a
13+
* valid abbreviation of "word".
14+
* <p>
15+
* Note:
16+
* Assume s contains only lowercase letters and abbr contains only lowercase letters and digits.
17+
* <p>
18+
* Example 1:
19+
* Given s = "internationalization", abbr = "i12iz4n":
20+
* Return true.
21+
* <p>
22+
* Example 2:
23+
* Given s = "apple", abbr = "a2e":
24+
* Return false.
25+
* <p>
26+
* Related Topics: String
27+
* <p>
28+
* Companies: Google
29+
* <p>
30+
* Similar Problems: Minimum Unique Word Abbreviation (H), Word Abbreviation (H)
31+
*/
32+
public class ValidWordAbbreviation {
33+
34+
/**
35+
* Word and abbreviation don't match if:
36+
* <ol>
37+
* <li>The lengths are different</li>
38+
* <li>The actual characters at specific positions are different</li>
39+
* </ol>
40+
* So iterate through abbreviation, track the position and compare the characters.
41+
* If there is a number, find the full number first then update indices.
42+
* The number abbreviates that many characters.
43+
* <p>
44+
* If there's no number, just compare the characters.
45+
* <p>
46+
* Both indices should be at the ends if it's a perfect match.
47+
*/
48+
public boolean validWordAbbreviation(String word, String abbr) {
49+
if (word == null && abbr == null) {
50+
return true;
51+
}
52+
if (word == null || abbr == null) {
53+
return false;
54+
}
55+
int pWord = 0;
56+
int pAbbr = 0;
57+
while (pWord < word.length() && pAbbr < abbr.length()) {
58+
int end = pAbbr;
59+
while (end < abbr.length() && '0' <= abbr.charAt(end) && abbr.charAt(end) <= '9') {
60+
end++;
61+
}
62+
if (end == pAbbr) { // No number, compare characters
63+
if (abbr.charAt(pAbbr) != word.charAt(pWord)) {
64+
return false;
65+
}
66+
pAbbr++;
67+
pWord++;
68+
} else {
69+
if (abbr.charAt(pAbbr) == '0') { // Edge case: should not have leading zero
70+
return false;
71+
}
72+
final int abbreviated = Integer.parseInt(abbr.substring(pAbbr, end));
73+
pWord += abbreviated;
74+
pAbbr = end;
75+
}
76+
}
77+
return pWord == word.length() && pAbbr == abbr.length();
78+
}
79+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.freetymekiyan.algorithms.level.easy;
2+
3+
import org.testng.Assert;
4+
import org.testng.annotations.DataProvider;
5+
import org.testng.annotations.Test;
6+
7+
public class ValidWordAbbreviationTest {
8+
9+
@DataProvider
10+
public Object[][] getExamples() {
11+
return new Object[][]{
12+
new Object[]{null, null, true},
13+
new Object[]{null, "", false},
14+
new Object[]{"", null, false},
15+
new Object[]{"internationalization", "i12iz4n", true},
16+
new Object[]{"apple", "a2e", false},
17+
new Object[]{"apple", "0a2e", false} // Edge case: leading zeros
18+
};
19+
}
20+
21+
@Test(dataProvider = "getExamples")
22+
public void testValidWordAbbreviation(String word, String abbr, boolean expected) {
23+
final boolean actual = new ValidWordAbbreviation().validWordAbbreviation(word, abbr);
24+
Assert.assertEquals(actual, expected);
25+
}
26+
}

0 commit comments

Comments
 (0)