ValidWordAbbreviation [source code]


public class ValidWordAbbreviation {
static
/******************************************************************************/
public class Solution {
    public boolean validWordAbbreviation(String word, String abbr) {
        if (word.length() == 0 && abbr.length() == 0) return true;
        if (word.length() < abbr.length() || word.length() == 0 || abbr.length() == 0) return false;
        String[] strW = word.split("");
        String[] strA = parseAbbr(abbr);
        int i = 0, j = 0;
        while (i < strW.length && j < strA.length) {
            if (strW[i].equals(strA[j])) {
                i++;
                j++;
            } else {
                try {
                    int skip = Integer.parseInt(strA[j]);
                    if (!strA[j].equals(Integer.toString(skip))) return false;
                    i += skip;
                    j++;
                } catch (Exception e) {
                    return false;
                }
            }
        }
        return i == strW.length && j == strA.length;
    }

    public String[] parseAbbr(String abbr) {
        char[] chs = abbr.toCharArray();
        List<String> res = new ArrayList<>();
        if (chs.length == 0) return new String[0];
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < chs.length; i++) {
            if (chs[i] < 'a') { //is number
                if ((i < chs.length - 1 && chs[i + 1] >= 'a') || i == chs.length - 1) {
                    res.add(sb.toString() + chs[i]);
                    sb.setLength(0);
                } else {
                    sb.append(chs[i]);
                }
            } else { //is not number
                res.add(String.valueOf(chs[i]));
            }
        }
        return res.toArray(new String[0]);
    }
}
/******************************************************************************/

    public static void main(String[] args) {
        ValidWordAbbreviation.Solution tester = new ValidWordAbbreviation.Solution();
        String[] inputs = {
            "word", "1ord", "1", 
            "word", "w2d", "1", 
            "word", "w1r1", "1", 
            "word", "4", "1",
            "internationalization", "i12iz4n", "1", 
            "apple", "a2e", "0",
            "hi", "1", "0",
            "hi", "02", "0",
        };
        for (int i = 0; i < inputs.length / 3; i++) {
            String word = inputs[3 * i];
            String abbr = inputs[1 + 3 * i];
            boolean expected = inputs[2 + 3 * i].equals("1");
            System.out.println(Printer.seperator());
            Printer.openColor("magenta");
            System.out.print(word + " AND " + abbr);
            Printer.closeColor();
            boolean output = tester.validWordAbbreviation(word, abbr);
            System.out.print(" -> " + output);
            Printer.openColor(output == expected ? "green" : "red");
            System.out.println(", expected: " + expected);
            Printer.closeColor();
        }
    }
}

这个题目其实思路非常简单, 就是一个跳子的思路, 只不过实现起来并没有那么trivial, 各种考察基本功, 这很Google;

关于split的一个小知识点:

java> "".split("").length  
java.lang.Integer res1 = 1  
java> "a".split("").length  
java.lang.Integer res2 = 1  
java> "ab".split("").length  
java.lang.Integer res3 = 2

可以看到split("")出来的length是不可靠的; 尤其是上面这两个都是1的情况;

分段题, 先判断entry再判断flag;(是这样吗? 好像先判断flag好一些?)

不过这一题其实用分段思路来做不好, 因为分段题我们关心的其实只有段落以内的, 也就是波峰波谷, 我们只关注波峰. 这里的最好用边沿判断的思路来做: 波峰和波谷都要考虑; 传统的流算法就可以做了, 实现起来实际上反而更简单; 具体的思路就是一个伸脚探路的思路;
不过真正的段落算法其实判断的也是上升沿和下降沿? 而且主要工作量其实集中在下降沿.

主函数里面的循环是一个双iterator循环, 这种同是iterate两个及以上array的, 直接用while循环来写好像直观一些;

        return i == strW.length && j == strA.length;

这一句还是挺有讲究的, 这个问题一个比较出问题的地方就在流尾的处理上面, 无论是i还是j, 都有可能会过冲 (如果abbr里面的数字不够, j就有可能第一个达到strA.length提前结束; 如果abbr里面有一个数字特别大, 那么i就会被过冲). 所以最后一定要判断两个都是和平结束(都是等于length的结束)才能说明整个循环走完是没有问题的;

最后的速度是35ms (6%), 有点失望; 感觉可能是各种JAVA自带的API用的太多了: exception, StringBuilder, list, Integer.parse;


这个是discussion上面一个跟我的做法比较类似的(iterate same speed at both arrays)解, 不过他写的还是简化很多, 虽然代码本身有些地方写的有点丑:

public boolean validWordAbbreviation(String word, String abbr) {  
    int i = 0, j = 0;  
    while (i < word.length() && j < abbr.length()) {  
        if (word.charAt(i) == abbr.charAt(j)) {  
            ++i;++j;  
            continue;  
        }  
        if (abbr.charAt(j) <= '0' || abbr.charAt(j) > '9') {  
            return false;  
        }  
        int start = j;  
        while (j < abbr.length() && abbr.charAt(j) >= '0' && abbr.charAt(j) <= '9') {  
            ++j;  
        }  
        int num = Integer.valueOf(abbr.substring(start, j));  
        i += num;  
    }  
    return i == word.length() && j == abbr.length();  
}

这是另一个, 代码写的好看一些:

public boolean validWordAbbreviation(String word, String abbr) {  
    int number = 0;  
    int i = 0, j = 0;  
    while (i < word.length() && j < abbr.length()) {  
        if (Character.isDigit(abbr.charAt(j))) {  
            number = number * 10 + abbr.charAt(j) - '0';  
            if (number == 0) return false;  
            j++;  
        } else {  
            i += number;  
            if (i >= word.length() || word.charAt(i) != abbr.charAt(j)) return false;  
            number = 0;  
            i++; j++;  
        }  
    }  
    i += number;  
    return i == word.length() && j == abbr.length();  
}

他这里对leading0的判断比较简练;


Problem Description

Given a non-empty string s and an abbreviation abbr, return whether the string matches with the given abbreviation.

A string such as "word" contains only the following valid abbreviations:

["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]
Notice that only the above abbreviations are valid abbreviations of the string "word". Any other string is not a valid abbreviation of "word".

Note:
Assume s contains only lowercase letters and abbr contains only lowercase letters and digits.

Example 1:
Given s = "internationalization", abbr = "i12iz4n":

Return true.
Example 2:
Given s = "apple", abbr = "a2e":

Return false.
Difficulty:Easy
Total Accepted:10.3K
Total Submissions:37K
Contributor: LeetCode
Companies
google
Related Topics
string
Similar Questions
Minimum Unique Word Abbreviation Word Abbreviation

results matching ""

    No results matching ""