LintCode上tag标记为String的题目大概有30多道题。
在我之前写的一篇LintCode位运算题总结的博文里有提到,此处便不再赘述。
给定一个string数组,要求找到这个数组里最长的单词是哪些。最简单的方法就是两趟遍历,第一趟统计最长的单词长度,第二趟统计有哪些单词满足这个长度,则取出来。
给定一个包含空格和单词的字符串,要求出其中最后一个单词的长度。这道题用java很好做,直接用String的split函数,把空格隔开,然后返回最后一个下标对应的字符串的长度就行:
public int lengthOfLastWord(String s) {
String[] res = s.split(" ");
if (res.length <= 0) {
return 0;
}
return res[res.length - 1].length();
}
157. Unique Characters
判断一个字符串里是否包含重复的字符。HashSet+一趟遍历即可。如果不让用HashSet,那就自己建立数组建Hash
判断两个String是否是同字母异序词。HashMap+两趟遍历即可。
public boolean anagram(String s, String t) {
HashMap<Character, Integer> hash = new HashMap();
for (int i = 0; i < s.length(); i++) {
if (hash.containsKey(s.charAt(i))) {
hash.put(s.charAt(i), hash.get(s.charAt(i)) + 1);
} else {
hash.put(s.charAt(i), 1);
}
}
for (int i = 0; i < t.length(); i++) {
if (hash.containsKey(t.charAt(i))) {
hash.put(t.charAt(i), hash.get(t.charAt(i)) - 1);
} else {
return false;
}
}
for (Character c : hash.keySet()) {
if (hash.get(c) != 0) {
return false;
}
}
return true;
}
55. Compare Strings
给定两个字符串A和B,判断A是否包含B里面的所有字符。跟上面那道题很类似,也是HashMap加两趟遍历搞定:
public boolean compareStrings(String A, String B) {
HashMap<Character, Integer> hash = new HashMap();
for (int i = 0; i < A.length(); i++) {
if (hash.containsKey(A.charAt(i))) {
hash.put(A.charAt(i), hash.get(A.charAt(i)) + 1);
} else {
hash.put(A.charAt(i), 1);
}
}
for (int i = 0; i < B.length(); i++) {
if (hash.containsKey(B.charAt(i))) {
hash.put(B.charAt(i), hash.get(B.charAt(i)) - 1);
if (hash.get(B.charAt(i)) < 0) {
return false;
}
} else {
return false;
}
}
return true;
}
420. Count and Say
题意是n=1时输出字符串1;n=2时,数上次字符串中的数值个数,因为上次字符串有1个1,所以输出11;n=3时,由于上次字符是11,有2个1,所以输出21;n=4时,由于上次字符串是21,有1个2和1个1,所以输出1211。依次类推,写个countAndSay(n)函数返回字符串。就用模拟的方法来就好,字符串的处理有点绕
public String countAndSay(int n) {
String s = "1";
if (n == 1) {
return s;
}
for (int i = 2; i <= n; i++) {
String res = "";
int index = 0;
while (index < s.length()) {
char now = s.charAt(index);
int count = 1;
while (index + 1 < s.length() && s.charAt(index + 1) == now) {
count++;
index++;
}
res = res + count;
res = res + now;
index++;
}
s = res;
}
return s;
}
把一个String里包含的所有单词逆转,比如"the sky is blue"变为"blue is sky the","the sky is blue"变为"blue is sky the"。多个空格当做一个空格来处理,开头和末尾不能包含空格。注意这道题在lintcode中直接用String.split(" ")是可以AC的,但是这是错的,因为同样一道题在leetcode中不能AC。所以得自己写一个类似split的函数来AC,用于处理多个空格连在一起的情况:
private ArrayList<String> findWord(String s) {
ArrayList<String> arr = new ArrayList<String>();
int index = 0;
while (index < s.length()) {
String word = "";
while (index < s.length() && s.charAt(index) != ' ') {
word += s.charAt(index);
index++;
}
if (word.length() > 0) {
arr.add(word);
}
index++;
}
return arr;
}
public String reverseWords(String s) {
ArrayList<String> res = findWord(s);
String word = "";
for (int i = res.size() - 1; i > 0; i--) {
word += res.get(i);
word += " ";
}
if (res.size() > 0) {
word += res.get(0);
}
return word;
}
要求把一个字符串进行旋转操作,如下所示:
Given "abcdefg"
.
offset=0 => "abcdefg"
offset=1 => "gabcdef"
offset=2 => "fgabcde"
offset=3 => "efgabcd"
如果可以借助一个额外的数组,就可以用下面这种方法:
public void rotateString(char[] str, int offset) {
if (str == null || str.length == 0 || offset < 0) {
return;
}
char[] res = new char[str.length];
if (offset > str.length) {
offset = offset % str.length;
}
for (int i = 0; i < str.length; i++) {
if (i + offset < str.length) {
res[i + offset] = str[i];
} else {
res[i + offset - str.length] = str[i];
}
}
for (int i = 0; i < str.length; i++) {
str[i] = res[i];
}
}
但是题目要求不能用到额外的空间,要就地进行。
给定一个character的数组,要求把里面的所有空格都替换为%20,要求不用到额外的空间。方法就是先遍历一遍数有多少个空格,然后我就可以计算出全部替换之后的长度了,然后我再从后往前扫描逐个替换。这样就用了2趟遍历做到了:
public int replaceBlank(char[] string, int length) {
int count = 0;
for (int i = 0; i < length; i++) {
if (string[i] == ' ') {
count++;
}
}
int newLength = length + count * 2;
int right = newLength - 1, left = length - 1;
while (right >= 0 && left >= 0) {
while (right >= 0 && left >= 0 && string[left] != ' ') {
string[right--] = string[left--];
}
while (right >= 0 && left >= 0 && string[left] == ' ') {
string[right--] = '0';
string[right--] = '2';
string[right--] = '%';
left--;
}
}
return newLength;
}
判断一个字符串是不是回文串,忽略大小写、空格、和其他字符。比如"A man, a plan, a canal: Panama" 是一个回文串。由于不允许使用额外的空间,所以得用双指针法从两端从中间进行扫描。
private boolean isDigitOrLetter(String s, int pos) {
if (s.charAt(pos) >= '0' && s.charAt(pos) <= '9' ) {
return true;
}
if (s.charAt(pos) >= 'a' && s.charAt(pos) <= 'z' ) {
return true;
}
if (s.charAt(pos) >= 'A' && s.charAt(pos) <= 'Z' ) {
return true;
}
return false;
}
public boolean isPalindrome(String s) {
s = s.toUpperCase();
int start = 0, end = s.length() - 1;
while (start < end) {
if (isDigitOrLetter(s, start) == false) {
start++;
continue;
}
if (isDigitOrLetter(s, end) == false) {
end--;
continue;
}
if (s.charAt(start) != s.charAt(end)) {
return false;
} else {
start++;
end--;
}
}
return true;
}
要求自己实现找子串函数,给定一个目标字符串A和一个字符串B,要求返回B在A中出现的第一个位置,若B不是A的子串,则返回-1。这道题考察的不是KMP,而是考你两重循环能不能写对,bug free。还真别说,这道题要做到bug free还真挺难的,边界处理条件啥的。
首先思路肯定是2层循环遍历,外层循环是遍历source,但是不需要遍历到source的最后一个下标,只要下标小于source.length() - target.length() + 1就可以打止了。
然后内层循环是遍历target,思路就是如果能够遍历完整内层循环的话,就说明找到了匹配,这个时候外层循环的下标i就是出现的第一个位置了。
如果内部循环的遍历发现了不匹配,即source.charAt(i + j) != target.charAt(j)的时候,就跳出循环。
public int strStr(String source, String target) {
if (source == null || target == null) {
return -1;
}
int i, j;
for (i = 0; i < source.length() - target.length() + 1; i++) {
for (j = 0; j < target.length(); j++) {
if (source.charAt(i + j) != target.charAt(j)) {
break;
}
}
if (j == target.length()) {
return i;
}
}
return -1;
}
给定一个字符串数组,要求把里面所有的同字母异序词全部返回。
Given ["ab", "ba", "cd", "dc", "e"]
, return ["ab", "ba", "cd", "dc"]
.
public List<String> anagrams(String[] strs) {
List<String> res = new ArrayList();
HashMap<String, String> map = new HashMap();
HashMap<String, Integer> count = new HashMap();
for (int i = 0; i < strs.length; i++) {
char[] arr = strs[i].toCharArray();
Arrays.sort(arr);
String sorted = new String(arr);
map.put(strs[i], sorted);
if (count.containsKey(sorted)) {
count.put(sorted, 1 + count.get(sorted));
} else {
count.put(sorted, 1);
}
}
for (int i = 0; i < strs.length; i++) {
String sorted = map.get(strs[i]);
if (count.get(sorted) > 1) {
res.add(strs[i]);
}
}
return res;
}
我是用两个HashMap搞定的,一个HashMap用于建立从原单词到有序单词的映射,比如abc、bac、cba都是映射到abc上,然后第二个HashMap用来统计abc出现的次数。然后第二次遍历的时候,我就对每个单词,查看它的映射出现的次数,如果出现超过1次,就说明有同字母异序词的存在,这个时候就把它加入结果。
给定数字,要求生成n对合法的括号。一道经典的递归题,在CC150上第五版的9.6有详解。这道题总的来说有2种方法。
第一种:每找到一个左括号,就在其后面加一个完整的括号,最后再在开头加一个(),就形成了所有的情况,需要注意的是,有时候会出现重复的情况,所以我们用set数据结构,好处是如果遇到重复项,不会加入到结果中,最后我们再把set转为vector即可:
n=1: ()
n=2: (()) ()()
n=3: (()()) ((())) ()(()) (())() ()()()
private String insertInside(String s, int pos) {
String left = s.substring(0, pos + 1);
String right = s.substring(pos + 1);
return left + "()" + right;
}
public ArrayList<String> generateParenthesis(int n) {
Set<String> res = new HashSet<String>();
if (n == 0) {
res.add("");
} else {
ArrayList<String> pre = generateParenthesis(n - 1);
for (String str : pre) {
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '(') {
res.add(insertInside(str, i));
}
}
res.add("()" + str);
}
}
return new ArrayList(res);
}
第二种方法:在每层递归中选择添加左括号还是右括号。递归函数有2个重要的参数:leftParen、rightParen,分别代表可以继续添加的左括号数量、右括号数量。
递归终止条件:若两者都为0,则说明没有括号可以添加了,此时就可以把当前结果添加到返回结果,并且return
子递归:若leftParen大于0,则添加左括号并进入下层递归。若rightParen大于0,则添加右括号并进入下层递归。
需要注意的是,若递归中出现了leftParen大于rightParen是非法情况,此时需要直接return不作处理
参考:http://www.cnblogs.com/grandyang/p/4444160.html
private void dfs(ArrayList<String> res, int left, int right, String path) {
if (left == 0 && right == 0) {
res.add(path);
return;
}
if (left > 0) {
dfs(res, left - 1, right, path + "(");
}
if (right > 0 && left < right) {
dfs(res, left, right - 1, path + ")");
}
}
public ArrayList<String> generateParenthesis(int n) {
ArrayList<String> res = new ArrayList<String>();
dfs(res, n, n, "");
return res;
}
418. Integer to Roman
整数转换为罗马数字,这道题就考你知不知道罗马数字的计数方式,记住就好:
public String intToRoman(int n) {
String res = "";
String[] roman = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
int[] val = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
for (int i = 0; i < 13; i++) {
while (n >= val[i]) {
res += roman[i];
n -= val[i];
}
}
return res;
}
罗马数字转换为整数,就是上道题的逆过程,可以参考这篇博文:https://segmentfault.com/a/1190000002683379
记得从右往左读取判断,遇到最大的之前都累加,如果遇到小的就减去它:
public int romanToInt(String s) {
HashMap<Character, Integer> map = new HashMap();
map.put('I', 1);
map.put('V', 5);
map.put('X', 10);
map.put('L', 50);
map.put('C', 100);
map.put('D', 500);
map.put('M', 1000);
int res = 0;
Character max = 'I';
for (int i = s.length() - 1; i >= 0; i--) {
if (map.get(s.charAt(i)) >= map.get(max)) {
max = s.charAt(i);
res += map.get(s.charAt(i));
} else {
res -= map.get(s.charAt(i));
}
}
return res;
}
78. Longest Common Prefix
给定一个字符串数组,要求找到他们的最长的公共前缀。假如那个字符串数组里面有ABCD四个String,有两种方法,
第一种是两两之间互相比较,先找到AB的公共前缀X,然后再把X去和C比较得到前缀Y,再把Y和D去比较得到最终的公共前缀。
第二种方法是先找到最短的String,最长的公共前缀的长度肯定不会超过最短的那个String的长度n,然后我就只要比较这些字符串的前n个字符就行了:
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
// 找到最短的单词的长度
int n = Integer.MAX_VALUE;
for (int i = 0; i < strs.length; i++) {
if (strs[i].length() <= n) {
n = strs[i].length();
}
}
int index;
for (index = 0; index < n; index++) {
int j;
for (j = 1; j < strs.length; j++) {
if (strs[j].charAt(index) != strs[0].charAt(index)) {
break;
}
}
if (j != strs.length) {
break;
}
}
return strs[0].substring(0, index);
}
200. Longest Palindromic Substring
给定一个String,要求找到它的最长的回文子串。参考博文:http://blog.csdn.net/soszou/article/details/37312317
可以用中心扩展法,因为回文字符串是以中心轴对称的,所以如果我们从下标 i 出发,用2个指针向 i 的两边扩展判断是否相等,那么只需要对0到 n-1的下标都做此操作,就可以求出最长的回文子串。需要注意的是要对长度为偶数和长度为奇数的回文串分别做处理:
private String findPalindrome(String s, int index) {
int left = index, right = index;
while (left >= 0 && right < s.length()) {
if (s.charAt(left) == s.charAt(right)) {
left--;
right++;
} else {
break;
}
}
return s.substring(left + 1, right);
}
private String findEven(String s, int pos1, int pos2) {
int left = pos1, right = pos2;
while (left >= 0 && right < s.length()) {
if (s.charAt(left) == s.charAt(right)) {
left--;
right++;
} else {
break;
}
}
return s.substring(left + 1, right);
}
public String longestPalindrome(String s) {
String res = "";
for (int i = 0; i < s.length(); i++) {
String palindrome = findPalindrome(s, i);
if (i + 1 < s.length()) {
String even = findEven(s, i, i + 1);
if (even.length() >= res.length()) {
res = even;
}
}
if (palindrome.length() >= res.length()) {
res = palindrome;
}
}
return res;
}
384. Longest Substring Without Repeating Characters
给定一个字符串,找到其中的一个最长的字串,使得这个子串不包含重复的字符。受到了这篇博文的启发:http://blog.csdn.net/feliciafay/article/details/16895637
使用left和right两个指针进行搜索,下标left代表候选的最长子串的开头,下标right代表候选的最长子串的结尾。
先假设left不动,那么在理想的情况下,我们希望可以一直右移right,直到right到达原字符串的结尾,此时right-left就构成了一个候选的最长子串。每次都维护一个max_length,就可以选出最长子串了。实际情况是,不一定可以一直右移right。
如果right下标对应的字符在之前已经出现过(假设它出现的上一个位置在k),并且这个k也在区间[left, right]的范围之内,那么就需要停止右移了。在下一次搜索中,left应该更新到k+1。(K用于记录这个元素上一次出现过的位置)。
举个栗子:abcdefc中,c1和c2重复了。那么下一次遍历,应该跨过出现重复的地方进行,否则找出来的候选串依然有重复字符,且长度还不如上次的搜索。所以下一次搜索,直接从c1的下一个字符d开始进行,也就是说,下一次搜寻中,left应该更新到k+1。
1)实现的时候,我们用一个HashMap用于记录每个字符上一次出现的位置。用双指针left、right来遍历和维护一个子串的区间。
2)当子串区间[left, right]里出现了重复元素时,我们就需要把那个重复元素在[left, right]区间中上一次出现的位置k拿出来,并把left重置为k+1。同时在HashMap中更新那个重复元素的位置,然后还需要处理的一个地方时不能让右指针right比left小,要让right指针保持在left的右边。如果此时right本来就在left右边,则继续让right往右挪1位。
3)如果子串区间[left, right]里没有出现了重复元素,那就一直让right自增扩大区间,并更新maxLength的信息。同时把每个元素出现的位置用HashMap保存下来。
有几个测例可以考虑一下:
aab
aabb
bbbbb
dvdf
an++--12a4
public int lengthOfLongestSubstring(String s) {
int left = 0, right = 0, max = 0;
// HashMap用于记录字符上一次出现的位置
HashMap<Character, Integer> map = new HashMap();
while (right < s.length() && left < s.length()) {
// 若有重复元素,则left标记为上一个重复元素 + 1
if (map.containsKey(s.charAt(right)) && map.get(s.charAt(right)) >= left) {
left = map.get(s.charAt(right)) + 1;
map.put(s.charAt(right), right);
if (right <= left) {
right = left + 1;
} else {
right++;
}
} else {
map.put(s.charAt(right), right);
max = (right - left + 1) > max ? (right - left + 1) : max;
right++;
}
}
return max;
}
425. Letter Combinations of a Phone Number
给定一个这样的手机数字键盘,要求输入某些数字后,返回所有可能的组合。比如输入23,得到的所有可能组合是["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
这种球所有组合的题目,十有八九得用DFS来做。
private String[] map = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
private void dfs(ArrayList<String> res, String path, String digits, int pos) {
if (pos >= digits.length()) {
res.add(path);
return;
}
String s = map[digits.charAt(pos) - '0'];
for (int i = 0; i < s.length(); i++) {
path += String.valueOf(s.charAt(i));
dfs(res, path, digits, pos + 1);
path = path.substring(0, path.length() - 1);
}
}
public ArrayList<String> letterCombinations(String digits) {
ArrayList<String> res = new ArrayList<String>();
if (digits == null || digits.length() == 0) {
return res;
}
dfs(res, "", digits, 0);
return res;
}
但是用String太耗费空间了,我们用StringBuilder这个类来做:
private String[] map = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
private void dfs(ArrayList<String> res, StringBuilder path, String digits, int pos) {
if (pos >= digits.length()) {
res.add(new String(path));
return;
}
String s = map[digits.charAt(pos) - '0'];
for (int i = 0; i < s.length(); i++) {
path.append(s.charAt(i));
dfs(res, path, digits, pos + 1);
path.deleteCharAt(path.length() - 1);
}
}
public ArrayList<String> letterCombinations(String digits) {
ArrayList<String> res = new ArrayList<String>();
if (digits == null || digits.length() == 0) {
return res;
}
dfs(res, new StringBuilder(), digits, 0);
return res;
}
421. Simplify Path
这是一道简化路径的题,给定一个Unix路径,要求简化后不改变原路径的意思。路径简化的依据是:
当字符串是空或者遇到”/../”,则需要返回一个"/"
当遇见"/a//b",则需要简化为"/a/b"
当遇到"//"则表示是本级目录,无需做任何操作。
当遇到"/./"则表示是本级目录,无需做任何特殊操作。
当遇到“/../"则需要返回上级目录,需检查上级目录是否为空。
这道题的核心思想是利用stack和string的split函数。首先利用split函数把原String分割开来,这样所有/这样的字符都没了,然后我们再把剩下的字符进行拼接,如果遇到".."就pop出之前的元素。否则就继续进行添加push。
需要注意的是要对 "/"、"//"、"///"这些情况进行处理。
public String simplifyPath(String path) {
String[] arr = path.split("/+");
String res = "/";
Stack<String> stack = new Stack();
for (int i = 0; i < arr.length; i++) {
if (arr[i].equals("..")) {
if (!stack.empty()) {
stack.pop();
}
} else if (!arr[i].equals(".") && !arr[i].equals("")) {
stack.push(arr[i]);
}
}
while (!stack.empty()) {
res = "/" + stack.pop() + res;
}
if (res.length() > 1) {
return res.substring(0, res.length() - 1);
}
return res;
}
给定一个IP地址,要求返回它所有可能的合法的IP地址组合。比如给定:25525511135,得到的结果是:"255.255.11.135", "255.255.111.35"
这种求所有可能组合的题目,还是DFS来做。有点类似于String Permutation那道题。由于IP的每段最多只能为3位数,所以要注意一下这一点,每次循环最多生成3个子串,以避免无法进入下层子递归。
递归终止条件:path的长度为4的时候就进入终止条件。如果此时pos还没遍历到初始字符串的最后一位,这说明生成的IP地址是非法的,不能加入res中,直接return返回;如果此时pos遍历到了初始字符串的最后一位,就把这个IP地址加入res中并返回。
递归核心:递归核心部分就是从pos位置开始遍历字符串s,由于每个IP段最多为3位数,所以循环的次数应该在三次以内。每次循环,就把当前区间的子串给取出来,判断一下是不是合法的(0到255),如果合法就添加到路径中。需要对0进行处理,假设当前区间取到的子串是0、00、01这种,怎么处理?0是合法的,00、01肯定不是合法的。
然后还需要注意的是初始字符串的长度必须在4到12之间。
private void dfs(ArrayList<String> res, ArrayList<String> path, String s, int pos) {
if (path.size() == 4) {
if (pos != s.length()) {
return;
}
StringBuilder sb = new StringBuilder();
for (String str : path) {
sb.append(str);
sb.append(".");
}
sb.deleteCharAt(sb.length() - 1);
res.add(new String(sb));
return;
}
for (int i = pos; i < s.length() && i <= pos + 2; i++) {
String tmp = s.substring(pos, i + 1);
if (!valid(tmp)) {
continue;
}
path.add(tmp);
dfs(res, path, s, i + 1);
path.remove(path.size() - 1);
}
}
private boolean valid(String s) {
if (s.charAt(0) == '0') {
return s.equals("0"); // to eliminate cases like "00", "01"
}
int num = Integer.parseInt(s);
return num >= 0 && num <= 255;
}
public ArrayList<String> restoreIpAddresses(String s) {
ArrayList<String> res = new ArrayList<String>();
if (s.length() < 4 || s.length() > 12) {
return res;
}
dfs(res, new ArrayList<String>(), s, 0);
return res;
}
参考了这篇博文:http://www.cnblogs.com/grandyang/p/4084408.html
这道题巨难,判断一个string是不是有效地数字表达式。思路:先移除前导零和后缀零,然后记录点和e的位置。再分情况讨论。
如果会正则表达式,这道题就巨简洁了:
public boolean isNumber(String s) {
if(s.trim().isEmpty()){
return false;
}
String regex = "[-+]?(\\d+\\.?|\\.\\d+)\\d*(e[-+]?\\d+)?";
if(s.trim().matches(regex)){
return true;
}else{
return false;
}
}
九章上的标准答案如下:
public boolean isNumber(String s) {
// skip leading and trailing whitespaces
s = s.trim();
if (s == null || s.length() == 0) {
return false;
}
int index = 0;
// skip leading +/-
if (s.charAt(index) == '+' || s.charAt(index) == '-') {
index++;
}
boolean num = false; // is a digit
boolean dot = false; // is a '.'
boolean exp = false; // is a 'e'
while (index < s.length()) {
char c = s.charAt(index);
if (Character.isDigit(c)) {
num = true;
} else if (c == '.') {
if (dot || exp) return false;
dot = true;
} else if (c == 'e') {
if (exp || num == false) return false;
exp = true;
num = false;
} else if (c == '+' || c == '-') {
if (s.charAt(index - 1) != 'e') return false;
} else {
return false;
}
index++;
}
return num;
}
相当于自己实现一个atoi的函数,把string转换成int。这道题就考察你想到的corner case够不够全面。比如给定的字符串可能是“ 123 ”,这个就得去掉首位的空格。比如给了你一个溢出int类型的数据:123123123123123,那你就只能返回int的最大值。假如给你一个" +-1111 ",那么这种非法的只能返回0.
考虑的情况足够多,就可以AC了:
private boolean valid(Character c) {
return c >= '0' && c <= '9';
}
public int atoi(String str) {
// 用一个double来存储结果
double res = 0;
if (str == null || str.length() == 0) {
return 0;
}
// 删除开头和末尾的空格
str = str.trim();
// 检查正负数
boolean aboveZero = true;
int i = 0;
if (str.charAt(i) == '+') {
i++;
} else if (str.charAt(i) == '-') {
i++;
aboveZero = false;
}
// 计算值
while(i < str.length() && valid(str.charAt(i))) {
res = res * 10 + (str.charAt(i) - '0');
i++;
}
if (aboveZero == false) {
res = -res;
}
// 处理超过int最大长度的情况
if (res > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
if (res < Integer.MIN_VALUE) {
return Integer.MIN_VALUE;
}
return (int) res;
}
在 LintCode数组题总结 这篇博文中有,不再赘述。
在 LintCode图论&搜索题总结 这篇博文中有,不再赘述。
在 LintCode位运算题总结 这篇博文中有,不再赘述。
154. Regular Expression Matching
这几道题的核心是动态规划,详情请参考我的LintCode动态规划总结题博文