题目地址:
https://www.lintcode.com/problem/valid-word-abbreviation/description
给定一个字符串
s
s
s,允许对其进行如下方式压缩得到字符串
t
t
t:
1、从左到右遍历
s
s
s,
t
t
t可以直接append
s
s
s中连续的若干字母;
2、
t
t
t可以append一个非零数字(不允许有开头
0
0
0),代替
s
s
s中连续的若干个字母。
现在给定一个字符串 s s s及另一个字符串 t t t,问字符串 t t t是否是字符串 s s s的合法的压缩形式。
思路是用两个指针分别遍历两个字符串,如果发现遇到相同字符则同时移动两个指针;否则的话,若发现 t t t的当前位置是字母,说明不匹配,返回false;否则说明遇到了数字,首先看一下其是否是开头 0 0 0,如果是,则返回false,如果不是,则解析出数字后,将 s s s的指针向后移动若干位,然后继续循环,进行比较。当有一个指针走出界了以后退出循环。如果确实是合法压缩的话,此时两个指针应该分别指向了两个字符串的末尾后一格,如果不是,则说明有不匹配的地方,返回false。代码如下:
public class Solution {
/**
* @param word: a non-empty string
* @param abbr: an abbreviation
* @return: true if string matches with the given abbr or false
*/
public boolean validWordAbbreviation(String word, String abbr) {
// write your code here
int i = 0, j = 0;
while (i < word.length() && j < abbr.length()) {
if (word.charAt(i) == abbr.charAt(j)) {
i++;
j++;
} else if (Character.isLetter(abbr.charAt(j))) {
return false;
} else {
// 运行到这里说明遇到了数字。如果是开头0则返回false
if (abbr.charAt(j) == '0') {
return false;
}
// 接下来解析出数字
int k = j;
while (k < abbr.length() && Character.isDigit(abbr.charAt(k))) {
k++;
}
// 解析出数字后,将i指针向后移动skip位,同时j移动到数字的后面一位
int skip = Integer.parseInt(abbr.substring(j, k));
i += skip;
j = k;
}
}
// 如果分别都走到了末尾则说明是合法压缩,返回true
return i == word.length() && j == abbr.length();
}
}
时间复杂度 O ( n ) O(n) O(n), n n n是 s s s的长度,空间 O ( 1 ) O(1) O(1)。