leetcode笔记—String

3. Longest Substring Without Repeating Characters (medium)

最长的无重复的子字符串

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
problem
 1 class Solution {
 2 public:
 3     int lengthOfLongestSubstring(string s) {
 4         vector<int> dict(256, -1);
 5         int start = -1, res = 0;
 6         for (int i = 0; i < s.size(); ++i) {
 7             if (dict[s[i]] > start)
 8                 start = dict[s[i]];
 9             res = max(res, i - start);
10             dict[s[i]] = i;
11         }
12         return res;
13     }
14 };
View Code

 


5. Longest Palindromic Substring (medium)

最长的对称子字符串

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example:

Input: "babad"

Output: "bab"

Note: "aba" is also a valid answer.
 

Example:

Input: "cbbd"

Output: "bb"
problem
 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         string res;
 5         int cnt = 0;
 6         for (int i = 0; i < s.size();) {
 7             int left = i, right = i;
 8             while (right + 1 < s.size() && s[right + 1] == s[i])
 9                 ++right;
10             i = right + 1;
11             while (left > 0 && right < s.size() - 1 && s[left - 1] == s[right + 1]) {
12                 --left;
13                 ++right;
14             }
15             if (right - left + 1 > cnt) {
16                 cnt = right - left + 1;
17                 res = s.substr(left, cnt);
18             }
19         }
20         return res;
21     }
22 };
View Code

 


6. ZigZag Conversion (medium)

以zigzag顺序重排字符串

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

P   A   H   N
A P L S I I G
Y   I   R
And then read line by line: "PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:

string convert(string text, int nRows);
convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".
problem
 1 // numRows == 1时,不能加减
 2 class Solution {
 3 public:
 4     string convert(string s, int numRows) {
 5         if (1 == numRows) return s;                // 
 6         vector<string> tmp(numRows, "");
 7         for (int i = 0, j = 0, step = 1; i < s.size(); j += step) {
 8             tmp[j].push_back(s[i++]);
 9             if (j == 0) step = 1;
10             else if (j == numRows - 1) step = -1;
11         }
12         for (int i = 1; i < numRows; ++i)
13             tmp[0] += tmp[i];
14         return tmp[0];
15     }
16 };
View Code

 


8. String to Integer (atoi) (medium)

字符串转数字

Implement atoi to convert a string to an integer.

Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.

Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button  to reset your code definition.

spoilers alert... click to show requirements for atoi.

Requirements for atoi:
The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.
problem
 1 class Solution {
 2 public:
 3     int myAtoi(string str) {
 4         long res = 0;
 5         int i = 0, sign = 1;
 6         while (i < str.size() && str[i] == ' ')
 7             ++i;
 8         if (str[i] == '+' || str[i] == '-')
 9             sign = str[i++] == '+' ? 1 : -1;
10         for (; i < str.size() && str[i] >= '0' && str[i] <='9'; ++i) {
11             res = res*10 + str[i] - '0';
12             if (res*sign > INT_MAX)
13                 return INT_MAX;
14             else if (res*sign < INT_MIN)
15                 return INT_MIN;
16         }
17         return (int)(res*sign);
18     }
19 };
View Code

 


10. Regular Expression Matching (hard) #

正则表达式匹配:.和*

problem
View Code
View Code

 


12. Integer to Roman (medium)

数字转罗马数字

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.
problem
 1 class Solution {
 2 public:
 3     string intToRoman(int num) {
 4         string M[] = {"", "M", "MM", "MMM"};
 5         string C[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
 6         string X[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
 7         string I[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
 8         return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10];
 9     }
10 };
View Code

 


13. Roman to Integer (easy)

罗马数字转普通数字

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.
problem
 1 class Solution {
 2 public:
 3     int romanToInt(string s) {
 4         unordered_map<char, int> T = { { 'I' , 1 },
 5                                      { 'V' , 5 },
 6                                      { 'X' , 10 },
 7                                      { 'L' , 50 },
 8                                      { 'C' , 100 },
 9                                      { 'D' , 500 },
10                                      { 'M' , 1000 } };
11         int sum = T[s.back()];
12         for (int i = s.length() - 2; i >= 0; --i)  {
13             if (T[s[i]] < T[s[i + 1]])
14                 sum -= T[s[i]];
15             else
16                 sum += T[s[i]];
17         }
18         return sum;
19     }
20 };
View Code

 


14. Longest Common Prefix (easy)

最长的公共前缀

Write a function to find the longest common prefix string amongst an array of strings.
problem
 1 class Solution {
 2 public:
 3     string longestCommonPrefix(vector<string>& strs) {
 4         if (strs.empty()) return "";
 5         string str1 = strs[0];
 6         for (int i = 1; i < strs.size(); ++i) {
 7             string str2 = strs[i];
 8             int index = 0;
 9             for (; str1[index] == str2[index]; ++index);
10             str1 = str1.substr(0, index);
11         }
12         return str1;
13     }
14 };
View Code

 


17. Letter Combinations of a Phone Number (medium) #

手机键盘输入组合

Given a digit string, return all possible letter combinations that the number could represent.

A mapping of digit to letters (just like on the telephone buttons) is given below.



Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.
problem
 1 class Solution {
 2 public:
 3     vector<string> letterCombinations(string digits) {
 4         if (digits.empty()) return vector<string>();
 5         vector<string> keyBoard  = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
 6         vector<string> res;
 7         res.push_back("");
 8         for (auto num : digits) {
 9             vector<string> tmp;
10             for (auto cur : res) {
11                 for (auto newChar : keyBoard[num - '0'])
12                     tmp.push_back(cur + newChar);
13             }
14             res.swap(tmp);
15         }
16         return res;
17     }
18 };
View Code

 


20. Valid Parentheses (easy)

判断()[]{}格式

Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.
problem
 1 class Solution {
 2 public:
 3     bool isValid(string s) {
 4         stack<char> st;
 5         for (auto c : s) {
 6             if (c == '(')
 7                 st.push(')');
 8             else if (c == '[')
 9                 st.push(']');
10             else if (c == '{')
11                 st.push('}');
12             else if (!st.empty() && st.top() == c)
13                 st.pop();
14             else
15                 return false;
16         }
17         return st.empty();
18     }
19 };
View Code

 


22. Generate Parentheses (medium) #

n个括号对的所有组合

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]
problem
 1 class Solution {
 2 public:
 3     vector<string> generateParenthesis(int n) {
 4         vector<string> res;
 5         string tmp;
 6         helper(res, tmp, n, 0);
 7         return res;
 8     }
 9     void helper(vector<string>& res, string tmp, int left, int right) {
10         if (left == 0 && right == 0) {
11             res.push_back(tmp);
12             return;
13         }
14         if (left > 0)
15             helper(res, tmp + "(", left - 1, right + 1);
16         if (right > 0)
17             helper(res, tmp + ")", left, right - 1);
18     }
19 };
View Code

 


28. Implement strStr() (easy)

字符串查找

Implement strStr().

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1:

Input: haystack = "hello", needle = "ll"
Output: 2
Example 2:

Input: haystack = "aaaaa", needle = "bba"
Output: -1
problem
 1 class Solution {
 2 public:
 3     int strStr(string haystack, string needle) {
 4         if (needle.empty())
 5             return 0;
 6         int res, i, j;
 7         for (res = 0; res <= (int)haystack.size() - (int)needle.size(); ++res) {
 8             for (i = res, j = 0; j < needle.size() && haystack[i] == needle[j]; ++i, ++j);
 9             if (j == needle.size())
10                 return res;
11         }
12         return -1;
13     }
14 };
View Code

 


30. Substring with Concatenation of All Words (hard) #

查找字符串,子串为words的组合

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).
problem
 1 class Solution {
 2 public:
 3     vector<int> findSubstring(string s, vector<string>& words) {
 4         vector<int> res;
 5         if (words.empty())
 6             return res;
 7         int length = words[0].size(), words_length = length*words.size();
 8         unordered_map<string, int> mp;
 9         for (string word : words)
10             ++mp[word];
11         for (int i = 0; i <= (int)s.size() - words_length; ++i) {
12             unordered_map<string, int> tmp_mp(mp);
13             int index = i;
14             while (index < i + words_length) {
15                 string word = s.substr(index, length);
16                 if (tmp_mp.find(word) != tmp_mp.end() && tmp_mp[word] > 0)
17                     --tmp_mp[word];
18                 else
19                     break;
20                 index += length;
21             }
22             if (index == i + words_length)
23                 res.push_back(i);
24         }
25         return res;
26     }
27 };
View Code

 


32. Longest Valid Parentheses (hard) #

最长的有效括号

problem
View Code
View Code

 


38. Count and Say (easy)

数字字符串描述

The count-and-say sequence is the sequence of integers with the first five terms as following:

1.     1
2.     11
3.     21
4.     1211
5.     111221
1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.
Given an integer n, generate the nth term of the count-and-say sequence.

Note: Each term of the sequence of integers will be represented as a string.

Example 1:

Input: 1
Output: "1"
Example 2:

Input: 4
Output: "1211"
problem
 1 class Solution {
 2 public:
 3     string countAndSay(int n) {
 4         if (!n) return "";
 5         string res = "1";
 6         while (--n) {
 7             string new_str;
 8             for (int i = 0; i < res.size(); ++i) {
 9                 int j = 1;
10                 while (i + 1 < res.size() && res[i + 1] == res[i]) {
11                     ++i;
12                     ++j;
13                 }
14                 new_str.push_back(j + '0');
15                 new_str.push_back(res[i]);
16             }
17             res = new_str;
18         }
19         return res;
20     }
21 };
View Code

 


43. Multiply Strings (medium)

字符串代表的两个数相乘,返回字符串

Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2.

Note:

The length of both num1 and num2 is < 110.
Both num1 and num2 contains only digits 0-9.
Both num1 and num2 does not contain any leading zero.
You must not use any built-in BigInteger library or convert the inputs to integer directly.
problem
 1 class Solution {
 2 public:
 3     string multiply(string num1, string num2) {
 4         int m = num1.size(), n = num2.size(), cnt = 0;
 5         string res(m + n, '0');
 6         for (int i = m - 1; i >= 0; --i) {
 7             for (int j = n - 1; j >= 0; --j) {
 8                 int tmp = (num1[i] - '0')*(num2[j] - '0') + res[i + j + 1] - '0';
 9                 res[i + j + 1] = tmp%10 + '0';
10                 res[i + j] += tmp/10;
11             }
12         }
13         for (; cnt < m + n - 1 && res[cnt] == '0'; ++cnt);
14         return res.substr(cnt);
15     }
16 };
View Code

 


44. Wildcard Matching (hard) #

通配正则表达式:*和?

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false
problem
 1 // dp
 2 class Solution {
 3 public:
 4     bool isMatch(string s, string p) {
 5         int m = s.size(), n = p.size();
 6         vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
 7         dp[0][0] = true;
 8         for (int i = 1; i <= n && p[i - 1] == '*'; ++i)
 9             dp[0][i] = true;
10         for (int i = 1; i <= m; ++i) {
11             for (int j = 1; j <= n; ++j) {
12                 if (s[i - 1] == p[j - 1] || p[j - 1] == '?')
13                     dp[i][j] = dp[i - 1][j - 1];
14                 else if (p[j - 1] == '*')
15                     dp[i][j] = dp[i][j - 1]||dp[i - 1][j];
16                 else
17                     dp[i][j] = false;
18             }
19         }
20         return dp[m][n];
21     }
22 };
View Code
 1 // reference
 2 // i,j从前到后,当j==*时,记录位置,匹配不符合时j退回*的后一个位置;i在匹配时记录,不匹配时返回匹配的起始位置
 3 class Solution {
 4 public:
 5     bool isMatch(string s, string p) {
 6         int m = s.size(), n = p.size(), i = 0, j = 0, star = -1, ii;
 7         while (i < m) {
 8             if (s[i] == p[j] || p[j] == '?') {
 9                 ++i; ++j;
10             }
11             else if (p[j] == '*') {
12                 star = j++;
13                 ii = i;
14             }
15             else if (star != -1){
16                 j = star + 1;
17                 i = ++ii;
18             }
19             else
20                 return false;
21         }
22         while (j < n && p[j] == '*')
23             ++j;
24         return j == n;
25     }
26 };
View Code

 


49. Group Anagrams (medium)

字符串分组,组成元素一致的分为一组

Given an array of strings, group anagrams together.

For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], 
Return:

[
  ["ate", "eat","tea"],
  ["nat","tan"],
  ["bat"]
]
Note: All inputs will be in lower-case.
problem
 1 // 使用质数的乘积表示字符串
 2 class Solution {
 3 public:
 4     vector<vector<string>> groupAnagrams(vector<string>& strs) {
 5         unordered_map<int, vector<string>> mp;
 6         vector<vector<string>> res;
 7         int prime[26] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103};
 8         for (string str : strs) {
 9             int key = 1;
10             for (auto c : str)
11                 key *= prime[c - 'a'];
12             mp[key].push_back(str);
13         }
14         for (auto pair : mp)
15             res.push_back(pair.second);
16         return res;
17     }
18 };
View Code

 


58. Length of Last Word (easy)

字符串中最后一个单词的长度

Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string.

If the last word does not exist, return 0.

Note: A word is defined as a character sequence consists of non-space characters only.

Example:

Input: "Hello World"
Output: 5
problem
 1 class Solution {
 2 public:
 3     int lengthOfLastWord(string s) {
 4         int res = 0, tail = s.size() - 1;
 5         while (tail >= 0 && s[tail] == ' ')
 6             --tail;
 7         while (tail >= 0 && s[tail--] != ' ')
 8             ++res;
 9         return res;
10     }
11 };
View Code

 


65. Valid Number (hard)

判断字符串是不是一个数字(题不好,没仔细看)

Validate if a given string is numeric.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button  to reset your code definition.
problem
 1 // 去掉首尾空格后,匹配 [-+]?(([0-9]+(.[0-9]*)?)|.[0-9]+)(e[-+]?[0-9]+)?
 2 class Solution {
 3 public:
 4     bool isNumber(string s) {
 5         int head = 0, tail = s.size() - 1;
 6         while (s[head] == ' ') ++head;
 7         while (s[tail] == ' ') --tail;
 8         s = s.substr(head, tail - head + 1);
 9         bool pointSeen = false;
10         bool eSeen = false;
11         bool numberSeen = false;
12         bool numberAfterE = true;
13         for(int i = 0; i < s.size(); i++) {
14             if ('0' <= s[i] && s[i] <= '9') {
15                 numberSeen = true;
16                 numberAfterE = true;
17             }
18             else if (s[i] == '.') {
19                 if(eSeen || pointSeen)
20                     return false;
21                 pointSeen = true;
22             }
23             else if (s[i] == 'e') {
24                 if(eSeen || !numberSeen)
25                     return false;
26                 numberAfterE = false;
27                 eSeen = true;
28             }
29             else if (s[i] == '-' || s[i] == '+')
30             {
31                 if(i != 0 && s[i-1] != 'e')
32                     return false;
33             }
34             else
35                 return false;
36         }
37         
38         return numberSeen && numberAfterE;
39     }
40 };
View Code

 


67. Add Binary (easy)

字符串表示的两个二进制数相加

Given two binary strings, return their sum (also a binary string).

For example,
a = "11"
b = "1"
Return "100".
problem
 1 class Solution {
 2 public:
 3     string addBinary(string a, string b) {
 4         string res = "";
 5         int i = a.size() - 1, j = b.size() - 1, sum = 0;
 6         while (i >= 0 || j >= 0 || sum) {
 7             if (i >= 0)
 8                 sum += a[i--] - '0';
 9             if (j >= 0)
10                 sum += b[j--] - '0';
11             res.push_back((char)sum%2 + '0');
12             sum = sum/2;
13         }
14         reverse(res.begin(), res.end());
15         return res;
16     }
17 };
View Code

 


68. Text Justification (hard) #

文本两端对齐

Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.

You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters.

Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.

For the last line of text, it should be left justified and no extra space is inserted between words.

For example,
words: ["This", "is", "an", "example", "of", "text", "justification."]
L: 16.

Return the formatted lines as:
[
   "This    is    an",
   "example  of text",
   "justification.  "
]
Note: Each word is guaranteed not to exceed L in length.

click to show corner cases.

Corner Cases:
A line other than the last line might contain only one word. What should you do in this case?
In this case, that line should be left-justified.
problem
 1 class Solution {
 2 public:
 3     vector<string> fullJustify(vector<string>& words, int maxWidth) {
 4         vector<string> res;
 5         for (int i = 0, length, cnt; i < words.size(); i += cnt) {
 6             for (length = 0, cnt = 0; i + cnt < words.size() && length + words[i + cnt].size() + cnt <= maxWidth; ++cnt)
 7                 length += words[i + cnt].size();
 8             string tmp(words[i]);
 9             for (int j = 1; j < cnt; ++j) {
10                 if (i + cnt == words.size())
11                     tmp.push_back(' ');
12                 else
13                     tmp.append(string((maxWidth - length)/(cnt - 1) + (j - 1 < (maxWidth - length)%(cnt - 1)), ' '));
14                 tmp.append(words[i + j]);
15             }
16             tmp.append(string(maxWidth - tmp.size(), ' '));
17             res.push_back(tmp);
18         }
19         return res;
20     }
21 };
View Code

 


71. Simplify Path (medium) #

简化unix路径文本

Given an absolute path for a file (Unix-style), simplify it.

For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
click to show corner cases.

Corner Cases:
Did you consider the case where path = "/../"?
In this case, you should return "/".
Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/".
In this case, you should ignore redundant slashes and return "/home/foo".
problem
 1 // 使用stringstream
 2 class Solution {
 3 public:
 4     string simplifyPath(string path) {
 5         stringstream ss(path);
 6         string tmp, res;
 7         vector<string> st;
 8         while (getline(ss, tmp, '/')) {
 9             if (tmp == "" || tmp == ".")
10                 continue;
11             else if (tmp == ".." && !st.empty())
12                 st.pop_back();
13             else if (tmp != "..")
14                 st.push_back(tmp);
15         }
16         for (string s : st)
17             res += "/" + s;
18         return res.empty() ? "/" : res;
19     }
20 };
View Code

 


72. Edit Distance (hard)

一个word经过增、删、该,最少几步到另一个word

Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

You have the following 3 operations permitted on a word:

a) Insert a character
b) Delete a character
c) Replace a character
problem
 1 class Solution {
 2 public:
 3     int minDistance(string word1, string word2) {
 4         vector<int> dp(word2.size() + 1);
 5         int pre = 0, tmp;
 6         for (int i = 0; i <= word2.size(); ++i)
 7             dp[i] = i;
 8         for (int i = 0; i < word1.size(); ++i) {
 9             pre = i;
10             dp[0] = i + 1;
11             for (int j = 0; j < word2.size(); ++j) {
12                 tmp = dp[j + 1];
13                 if (word1[i] == word2[j])
14                     dp[j + 1] = pre;
15                 else
16                     dp[j + 1] = min(dp[j], min(dp[j + 1], pre)) + 1;
17                 pre = tmp;
18             }
19         }
20         return dp[word2.size()];
21     }
22 };
View Code

 


76. Minimum Window Substring (hard) #

最小的包含某子串的窗口

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC".

Note:
If there is no such window in S that covers all characters in T, return the empty string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
problem
 1 // 用count记录当前子串中缺少的元素个数,省去了每次验证map是否都小于0
 2 class Solution {
 3 public:
 4     string minWindow(string s, string t) {
 5         vector<int> mp(128, 0);
 6         for (auto c : t)
 7             ++mp[c];
 8         int begin = 0, end = 0, count = t.size(), length = INT_MAX, start = 0;
 9         while (end < s.size()) {
10             if (mp[s[end++]]-- > 0)
11                 --count;
12             while (count == 0) {
13                 if (length > end - begin)
14                     length = end - (start = begin);
15                 if (++mp[s[begin++]] > 0)
16                     ++count;
17             }
18         }
19         return length == INT_MAX ? "" : s.substr(start, length);
20     }
21 };
View Code

 


87. Scramble String (hard)

旋转单词:判断一个单词是否由另一个单词多次旋转得到

Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.

Below is one possible representation of s1 = "great":

    great
   /    \
  gr    eat
 / \    /  \
g   r  e   at
           / \
          a   t
To scramble the string, we may choose any non-leaf node and swap its two children.

For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat".

    rgeat
   /    \
  rg    eat
 / \    /  \
r   g  e   at
           / \
          a   t
We say that "rgeat" is a scrambled string of "great".

Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae".

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a
We say that "rgtae" is a scrambled string of "great".

Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.
problem
 1 class Solution {
 2 public:
 3     bool isScramble(string s1, string s2) {
 4         if (s1 == s2)
 5             return true;
 6         int length = s1.size();
 7         if (length != s2.size())
 8             return false;
 9         vector<int> count(26, 0);
10         for (int i = 0; i < length; ++i) {
11             ++count[s1[i] - 'a'];
12             --count[s2[i] - 'a'];
13         }
14         for (int c : count) {
15             if (c != 0)
16                 return false;
17         }
18         for (int i = 1; i < length; ++i) {
19             if ((isScramble(s1.substr(0,i), s2.substr(0,i)) && isScramble(s1.substr(i), s2.substr(i))) || \
20                 (isScramble(s1.substr(0,i), s2.substr(length-i)) && isScramble(s1.substr(i), s2.substr(0,length-i))))
21                 return true;
22         }
23         return false;
24     }
25 };
View Code

 


91. Decode Ways (hard) #

把数字序号解析为字母的方式数量

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.

For example,
Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).

The number of ways decoding "12" is 2.
problem
 1 // 1 类似“1502”这样的是不存在的;2 从前往后解析会出现res减小的情况,不易处理
 2 class Solution {
 3 public:
 4     int numDecodings(string s) {
 5         int n = s.size();
 6         if (n == 0)
 7             return 0;
 8         int res = s.back() == '0' ? 0 : 1, lst = 1, num = s.back() - '0', tmp = 0;
 9         for (int i = n - 2; i >= 0; --i) {
10             tmp = res;
11             if (s[i] == '0')
12                 res = 0;
13             else if (num + (s[i] - '0')*10 <= 26)
14                 res += lst;
15             lst = tmp;
16             num = s[i] - '0';
17         }
18         return res;
19     }
20 };
View Code

 


93. Restore IP Addresses (medium)

把字符串解析为IP地址

Given a string containing only digits, restore it by returning all possible valid IP address combinations.

For example:
Given "25525511135",

return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)
problem
 1 class Solution {
 2 public:
 3     vector<string> restoreIpAddresses(string s) {
 4         int length = s.size();
 5         vector<string> res;
 6         for (int i = 1; i < 4 && i < length - 2; ++i) {
 7             for (int j = i + 1; j < i + 4 && j < length - 1; ++j) {
 8                 for (int k = j + 1; k < j + 4 && k < length; ++k) {
 9                     string str1 = s.substr(0, i);
10                     string str2 = s.substr(i, j - i);
11                     string str3 = s.substr(j, k - j);
12                     string str4 = s.substr(k, length - k);
13                     if (isValid(str1) && isValid(str2) && isValid(str3) && isValid(str4)) {
14                         res.push_back(str1 + "." + str2 + "." + str3 + "." + str4);
15                     }
16                 }
17             }
18         }
19         return res;
20     }
21     bool isValid(string str) {
22         if (str.size() > 3 || (str.size() > 1 && str[0] == '0') || stoi(str) > 255) return false;
23         return true;
24     }
25 };
View Code

 


97. Interleaving String (hard)

判断两个字符串是否能组合成另一个字符串

Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.

For example,
Given:
s1 = "aabcc",
s2 = "dbbca",

When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.
problem
 1 // 递归会有2%超时
 2 class Solution {
 3 public:
 4     bool isInterleave(string s1, string s2, string s3) {
 5         int m = s1.size(), n = s2.size(), mn = s3.size();
 6         if (m + n != mn)
 7             return false;
 8         vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
 9         dp[0][0] = true;
10         for (int j = 1; j <= n; ++j)
11             dp[0][j] = s2[j - 1] == s3[j - 1] && dp[0][j - 1];
12         for (int i = 1; i <= m; ++i) {
13             dp[i][0] = s1[i - 1] == s3[i - 1] && dp[i - 1][0];
14             for (int j = 1; j <= n; ++j) {
15                 dp[i][j] = (s1[i - 1] == s3[i + j - 1] && dp[i - 1][j]) || \
16                            (s2[j - 1] == s3[i + j - 1] && dp[i][j - 1]);
17             }
18         }
19         return dp[m][n];
20     }
21 };
View Code

 


115. Distinct Subsequences (hard)

 一个string删除某些字母后得到另一个string的方式数量

Given a string S and a string T, count the number of distinct subsequences of S which equals T.

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).

Here is an example:
S = "rabbbit", T = "rabbit"

Return 3.
problem
 1 class Solution {
 2 public:
 3     int numDistinct(string s, string t) {
 4         int m = s.size(), n = t.size();
 5         vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
 6         dp[0][0] = 1;
 7         for (int i = 1; i <= m; ++i) {
 8             for (int j = 0; j <= i && j <= n; ++j) {
 9                 if (j > 0 && s[i - 1] == t[j - 1])
10                     dp[i][j] += dp[i - 1][j - 1];
11                 if (j != i)
12                     dp[i][j] += dp[i - 1][j];
13             }
14         }
15         return dp[m][n];
16     }
17 };
View Code

 


125. Valid Palindrome (easy)

判断回文

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.
problem
 1 class Solution {
 2 public:
 3     bool isPalindrome(string s) {
 4         for (int left = 0, right = s.size() - 1; left < right; ++left, --right) {
 5             while (left < right && !isalnum(s[left])) ++left;
 6             while (left < right && !isalnum(s[right])) --right;
 7             if (toupper(s[left]) != toupper(s[right])) return false;
 8         }
 9         return true;
10     }
11 };
View Code

 


126. Word Ladder II (hard) #

单词接龙,前后单词只有一个字母不同

problem
View Code

 


151. Reverse Words in a String (medium)

反转string中的word,并去掉头尾空格

Given an input string, reverse the string word by word.

For example,
Given s = "the sky is blue",
return "blue is sky the".

Update (2015-02-12):
For C programmers: Try to solve it in-place in O(1) space.

click to show clarification.

Clarification:
What constitutes a word?
A sequence of non-space characters constitutes a word.
Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces.
How about multiple spaces between two words?
Reduce them to a single space in the reversed string.
problem
 1 class Solution {
 2 public:
 3     void reverseWords(string &s) {
 4         int length = s.size();
 5         reverse(s.begin(), s.end());
 6         int temp = 0, i = 0;
 7         for (int j = 0; j < length;) {
 8             while (j < length && s[j] == ' ') ++j;
 9             if (j == length) break;
10             while (j < length && s[j] != ' ') s[i++] = s[j++];
11             reverse(s.begin() + temp, s.begin() + i);
12             s[i++] = ' ';
13             temp = i;
14         }
15         if (i == 0) temp = 1;
16         s.erase(s.begin() + temp - 1, s.end());
17     }
18 };
View Code

 


165. Compare Version Numbers (medium)

版本大小判断

Compare two version numbers version1 and version2.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.

You may assume that the version strings are non-empty and contain only digits and the . character.
The . character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.

Here is an example of version numbers ordering:

0.1 < 1.1 < 1.2 < 13.37
problem
 1 class Solution {
 2 public:
 3     int compareVersion(string version1, string version2) {
 4         int num1, num2, i = 0, j = 0;
 5         while (i < version1.size() || j < version2.size()) {
 6             num1 = num2 = 0;
 7             while (i < version1.size() && version1[i] != '.')
 8                 num1 = num1*10 + version1[i++] - '0';
 9             while (j < version2.size() && version2[j] != '.')
10                 num2 = num2*10 + version2[j++] - '0';
11             if (num1 != num2)
12                 return num1 < num2 ? -1 : 1;
13             ++i;++j;
14         }
15         return 0;
16     }
17 };
View Code

 


214. Shortest Palindrome (hard) #

把字符串补成回文串,只能在字符串前面补

Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.

For example:

Given "aacecaaa", return "aaacecaaa".

Given "abcd", return "dcbabcd".

Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Thanks to @Freezen for additional test cases.
problem
 1 // 反转后查找最长的匹配字符串,kmp算法
 2 class Solution {
 3 public:
 4     string shortestPalindrome(string s) {
 5         string rev_s(s);
 6         reverse(rev_s.begin(), rev_s.end());
 7         string ss = s + "#" + rev_s;
 8         vector<int> kmp(ss.size(), 0);
 9         for (int i = 1, index = 0; i < ss.size(); ++i) {
10             if (ss[i] == ss[index]) {
11                 kmp[i] = kmp[i - 1] + 1;
12                 ++index;
13             }
14             else {
15                 index = kmp[i - 1];
16                 while (index > 0 && ss[index] != ss[i])
17                     index = kmp[index - 1];
18                 if (ss[index] == ss[i])
19                     ++index;
20                 kmp[i] = index;
21             }
22         }
23         return ss.substr(s.size() + 1, s.size() - kmp[ss.size() - 1]) + s;
24     }
25 };
View Code
 1 // 简化版
 2 class Solution {
 3 public:
 4     string shortestPalindrome(string s) {
 5         string rev_s(s);
 6         reverse(rev_s.begin(), rev_s.end());
 7         string ss = s + "#" + rev_s;
 8         vector<int> kmp(ss.size(), 0);
 9         for (int i = 1; i < ss.size(); ++i) {
10             int index = kmp[i - 1];
11             while (index > 0 && ss[index] != ss[i])
12                 index = kmp[index - 1];
13             kmp[i] = (index += (ss[index] == ss[i]));
14         }
15         return ss.substr(s.size() + 1, s.size() - kmp[ss.size() - 1]) + s;
16     }
17 };
View Code

 


227. Basic Calculator II (medium)

字符串计算器

Implement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero.

You may assume that the given expression is always valid.

Some examples:
"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5
Note: Do not use the eval built-in library function.
problem
 1 class Solution {
 2 public:
 3     int calculate(string s) {
 4         vector<int> nums{0};
 5         int tmp = 0;
 6         char sign = '+';
 7         for (int i = 0; i <= s.size(); ++i) {
 8             if (i < s.size() && s[i] >= '0' && s[i] <= '9')
 9                 tmp = tmp*10 + s[i] - '0';
10             else if (i < s.size() && s[i] == ' ')
11                 continue;
12             else {
13                 if (sign == '+')
14                     nums.push_back(tmp);
15                 else if (sign == '-')
16                     nums.push_back(-tmp);
17                 else if (sign == '*')
18                     nums.back() = nums.back()*tmp;
19                 else if (sign == '/')
20                     nums.back() = nums.back()/tmp;
21                 if (i < s.size())
22                     sign = s[i];
23                 tmp = 0;
24             }
25         }
26         return accumulate(nums.begin(), nums.end(), 0);
27     }
28 };
View Code

 


273. Integer to English Words (hard)

数字用英文单词表示

Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 1.

For example,
123 -> "One Hundred Twenty Three"
12345 -> "Twelve Thousand Three Hundred Forty Five"
1234567 -> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
problem
 1 // 没做
 2 class Solution {
 3 public:
 4     static string numberToWords(int n) {
 5         if(n == 0) return "Zero";
 6         else return int_string(n).substr(1);
 7     }
 8 private:
 9     static const char * const below_20[];
10     static const char * const below_100[];
11     static string int_string(int n) {
12         if(n >= 1000000000)   return int_string(n / 1000000000) + " Billion" + int_string(n - 1000000000 * (n / 1000000000));
13         else if(n >= 1000000) return int_string(n / 1000000) + " Million" + int_string(n - 1000000 * (n / 1000000));
14         else if(n >= 1000)    return int_string(n / 1000) + " Thousand" + int_string(n - 1000 * (n / 1000));
15         else if(n >= 100)     return int_string(n / 100) + " Hundred" + int_string(n - 100 * (n / 100));
16         else if(n >= 20)      return string(" ") + below_100[n / 10 - 2] + int_string(n - 10 * (n / 10));
17         else if(n >= 1)       return string(" ") + below_20[n - 1];
18         else return "";
19     }
20 };
21 
22 const char * const Solution::below_20[] =  {"One", "Two", "Three", "Four","Five","Six","Seven","Eight","Nine","Ten", "Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"};
23 const char * const Solution::below_100[] = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
View Code

 


336. Palindrome Pairs (hard) ###########################

能组成回文的字符串对

 


344. Reverse String (easy)

翻转字符串

Write a function that takes a string as input and returns the string reversed.

Example:
Given s = "hello", return "olleh".
problem
1 class Solution {
2 public:
3     string reverseString(string s) {
4         for (int i = 0, j = s.size() - 1; i < j; ++i, --j)
5             swap(s[i], s[j]);
6         return s;
7     }
8 };
View Code

 


345. Reverse Vowels of a String (easy)

翻转字符串中的元音字母

Write a function that takes a string as input and reverse only the vowels of a string.

Example 1:
Given s = "hello", return "holle".

Example 2:
Given s = "leetcode", return "leotcede".

Note:
The vowels does not include the letter "y".
problem
 1 class Solution {
 2 public:
 3     string reverseVowels(string s) {
 4         bool m[255] = {0};
 5         string vowels = "aeiouAEIOU";
 6         for (auto c : vowels)
 7             m[c] = 1;
 8         for (int i = 0, j = s.size() - 1; i < j; ++i, --j) {
 9             while (i < s.size() && !m[s[i]])
10                 ++i;
11             while (j > i && !m[s[j]])
12                 --j;
13             if (i < j)
14                 swap(s[i], s[j]);
15         }
16         return s;
17     }
18 };
View Code

 


383. Ransom Note (easy)

后面的字符串可否由前面的字符串加一些字母组成

Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false.

Each letter in the magazine string can only be used once in your ransom note.

Note:
You may assume that both strings contain only lowercase letters.

canConstruct("a", "b") -> false
canConstruct("aa", "ab") -> false
canConstruct("aa", "aab") -> true
problem
 1 class Solution {
 2 public:
 3     bool canConstruct(string ransomNote, string magazine) {
 4         vector<int> dict(26);
 5         for (auto m : magazine) dict[m - 'a']++;
 6         for (auto r : ransomNote)
 7             if (--dict[r - 'a'] < 0) return false;
 8         return true;
 9     }
10 };
View Code

 


385. Mini Parser (medium) #

解析字符串到对象

Given a nested list of integers represented as a string, implement a parser to deserialize it.

Each element is either an integer, or a list -- whose elements may also be integers or other lists.

Note: You may assume that the string is well-formed:

String is non-empty.
String does not contain white spaces.
String contains only digits 0-9, [, - ,, ].
Example 1:

Given s = "324",

You should return a NestedInteger object which contains a single integer 324.
Example 2:

Given s = "[123,[456,[789]]]",

Return a NestedInteger object containing a nested list with 2 elements:

1. An integer containing value 123.
2. A nested list containing two elements:
    i.  An integer containing value 456.
    ii. A nested list with one element:
         a. An integer containing value 789.
problem
 1 /**
 2  * // This is the interface that allows for creating nested lists.
 3  * // You should not implement it, or speculate about its implementation
 4  * class NestedInteger {
 5  *   public:
 6  *     // Constructor initializes an empty nested list.
 7  *     NestedInteger();
 8  *
 9  *     // Constructor initializes a single integer.
10  *     NestedInteger(int value);
11  *
12  *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
13  *     bool isInteger() const;
14  *
15  *     // Return the single integer that this NestedInteger holds, if it holds a single integer
16  *     // The result is undefined if this NestedInteger holds a nested list
17  *     int getInteger() const;
18  *
19  *     // Set this NestedInteger to hold a single integer.
20  *     void setInteger(int value);
21  *
22  *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
23  *     void add(const NestedInteger &ni);
24  *
25  *     // Return the nested list that this NestedInteger holds, if it holds a nested list
26  *     // The result is undefined if this NestedInteger holds a single integer
27  *     const vector<NestedInteger> &getList() const;
28  * };
29  */
30 class Solution {
31 public:
32     NestedInteger deserialize(string s) {
33         auto isNumber = [](char c) {return (c == '-' || isdigit(c));};
34         stack<NestedInteger> st;
35         st.push(NestedInteger());
36         for (auto it = s.begin(); it != s.end();) {
37             auto c = *it;
38             if (isNumber(c)) {
39                 auto it2 = find_if_not(it, s.end(), isNumber);
40                 int val = stoi(string(it, it2));
41                 st.top().add(NestedInteger(val));
42                 it = it2;
43             }
44             else {
45                 if (c == '[')
46                     st.push(NestedInteger());
47                 else if (c == ']') {
48                     NestedInteger tmp = st.top();
49                     st.pop();
50                     st.top().add(tmp);
51                 }
52                 ++it;
53             }
54         }
55         return st.top().getList().front();
56     }
57 };
View Code

 


387. First Unique Character in a String (easy)

第一个不重复的元素

Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.

Examples:

s = "leetcode"
return 0.

s = "loveleetcode",
return 2.
Note: You may assume the string contain only lowercase letters.
problem
 1 class Solution {
 2 public:
 3     int firstUniqChar(string s) {
 4         int frq[26] = {0};
 5         for (auto c : s)
 6             ++frq[c - 'a'];
 7         for (int i = 0; i < s.size(); ++i) {
 8             if (frq[s[i] - 'a'] == 1)
 9                 return i;
10         }
11         return -1;
12     }
13 };
View Code

 


434. Number of Segments in a String (easy)

字符串中以空格分隔的块个数

Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters.

Please note that the string does not contain any non-printable characters.

Example:

Input: "Hello, my name is John"
Output: 5
problem
 1 class Solution {
 2 public:
 3     int countSegments(string s) {
 4         int res = 0;
 5         s.push_back(' ');
 6         for(int i = 1; i < s.size(); ++i)
 7           if(s[i] == ' ' && s[i-1] != ' ') ++res;
 8         return res;
 9     }
10 };
View Code

 


443. String Compression (easy)

字符串压缩,在原位置压缩,返回压缩后的大小

Given an array of characters, compress it in-place.

The length after compression must always be smaller than or equal to the original array.

Every element of the array should be a character (not int) of length 1.

After you are done modifying the input array in-place, return the new length of the array.


Follow up:
Could you solve it using only O(1) extra space?


Example 1:
Input:
["a","a","b","b","c","c","c"]

Output:
Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"]

Explanation:
"aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3".
Example 2:
Input:
["a"]

Output:
Return 1, and the first 1 characters of the input array should be: ["a"]

Explanation:
Nothing is replaced.
Example 3:
Input:
["a","b","b","b","b","b","b","b","b","b","b","b","b"]

Output:
Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"].

Explanation:
Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12".
Notice each digit has it's own entry in the array.
Note:
All characters have an ASCII value in [35, 126].
1 <= len(chars) <= 1000.
problem
 1 class Solution {
 2 public:
 3     int compress(vector<char>& chars) {
 4         int index = 0;
 5         for (int i = 0; i < chars.size(); ++i) {
 6             char cur = chars[i];
 7             int cnt = 1;
 8             while (i + 1 < chars.size() && chars[i + 1] == cur) {
 9                 ++i;
10                 ++cnt;
11             }
12             chars[index++] = cur;
13             if (cnt > 1) {
14                 string num = to_string(cnt);
15                 for (char n : num)
16                     chars[index++] = n;
17             }
18         }
19         return index;
20     }
21 };
View Code

 


459. Repeated Substring Pattern (easy) #

判断字符串是否可拆分为多个相同的子串

Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000.
Example 1:
Input: "abab"

Output: True

Explanation: It's the substring "ab" twice.
Example 2:
Input: "aba"

Output: False
Example 3:
Input: "abcabcabcabc"

Output: True

Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.)
problem
 1 // KMP
 2 class Solution {
 3 public:
 4     bool repeatedSubstringPattern(string s) {
 5         int length = s.size();
 6         vector<int> dp(length, 0);
 7         for (int i = 1, j = 0; i < length;) {
 8             if (s[j] == s[i])
 9                 dp[i++] = ++j;
10             else if (j > 1)
11                 j = dp[j - 1];
12             else
13                 ++i;
14         }
15         return dp[length - 1] && length%(length - dp[length - 1]) == 0;
16     }
17 };
View Code
 1 // 最后不能是ss.find(s, 1) >= 0。
 2 // 
 3 class Solution {
 4 public:
 5     bool repeatedSubstringPattern(string s) {
 6         if (s.size() < 2)
 7             return false;
 8         string ss = s + s;
 9         ss.pop_back();
10         return ss.find(s, 1) != -1;
11     }
12 };
View Code

 


468. Validate IP Address (medium) #

判断IP地址是否正确

Write a function to check whether an input string is a valid IPv4 address or IPv6 address or neither.

IPv4 addresses are canonically represented in dot-decimal notation, which consists of four decimal numbers, each ranging from 0 to 255, separated by dots ("."), e.g.,172.16.254.1;

Besides, leading zeros in the IPv4 is invalid. For example, the address 172.16.254.01 is invalid.

IPv6 addresses are represented as eight groups of four hexadecimal digits, each group representing 16 bits. The groups are separated by colons (":"). For example, the address 2001:0db8:85a3:0000:0000:8a2e:0370:7334 is a valid one. Also, we could omit some leading zeros among four hexadecimal digits and some low-case characters in the address to upper-case ones, so 2001:db8:85a3:0:0:8A2E:0370:7334 is also a valid IPv6 address(Omit leading zeros and using upper cases).

However, we don't replace a consecutive group of zero value with a single empty group using two consecutive colons (::) to pursue simplicity. For example, 2001:0db8:85a3::8A2E:0370:7334 is an invalid IPv6 address.

Besides, extra leading zeros in the IPv6 is also invalid. For example, the address 02001:0db8:85a3:0000:0000:8a2e:0370:7334 is invalid.

Note: You may assume there is no extra space or special characters in the input string.

Example 1:
Input: "172.16.254.1"

Output: "IPv4"

Explanation: This is a valid IPv4 address, return "IPv4".
Example 2:
Input: "2001:0db8:85a3:0:0:8A2E:0370:7334"

Output: "IPv6"

Explanation: This is a valid IPv6 address, return "IPv6".
Example 3:
Input: "256.256.256.256"

Output: "Neither"

Explanation: This is neither a IPv4 address nor a IPv6 address.
problem
 1 class Solution {
 2 public:
 3     /*
 4     string validIPAddress(string IP) {
 5         string res[3] = {"IPv4", "IPv6", "Neither"};
 6         stringstream ss(IP);
 7         string block;
 8         int cnt;
 9         if (IP.substr(0, 4).find('.') != string::npos) {
10             for (cnt = 0; getline(ss, block, '.'); ++cnt) {
11                 if (cnt >= 4 || !validIPv4(block))
12                     return res[2];
13             }
14             return cnt == 4 ? res[0] : res[2];
15         }
16         else if (IP.substr(0, 5).find(':') != string::npos) {
17             for (cnt = 0; getline(ss, block, ':'); ++cnt) {
18                 if (cnt >= 8 || !validIPv6(block))
19                     return res[2];
20             }
21             return ss.eof() ? res[1] : res[2];
22         }
23         return res[2];
24     }
25     */
26     
27     string validIPAddress(string IP) {
28         string ans[3] = {"IPv4", "IPv6", "Neither"};
29         stringstream ss(IP);
30         string block;
31         // ipv4 candidate
32         if (IP.substr(0, 4).find('.') != string::npos) {
33             for (int i = 0; i < 4; i++) {
34             if (!getline(ss, block, '.') || !validIPv4(block))
35                    return ans[2];
36             }
37             return ss.eof() ? ans[0] : ans[2];
38         }
39         // ipv6 candidate
40         else if (IP.substr(0, 5).find(':') != string::npos) {
41             for (int i = 0; i < 8; i++) {
42             if (!getline(ss, block, ':') || !validIPv6(block))
43                 return ans[2];
44             }
45             return ss.eof() ? ans[1] : ans[2];
46         }
47     
48         return ans[2];
49     }
50     const string validIPv6Chars = "0123456789abcdefABCDEF";
51     
52     bool validIPv4(string& block) {
53         int num = 0;
54         if (block.size() > 0 && block.size() <= 3) {
55             for (int i = 0; i < block.size(); i++) {
56                 char c = block[i];
57                 // special case: if c is a leading zero and there are characters left
58                 if (!isalnum(c) || (i == 0 && c == '0' && block.size() > 1))
59                     return false;
60                 else {
61                     num *= 10;
62                     num += c - '0';
63                 }
64             }
65             return num <= 255;
66         }
67         return false;
68     }
69     
70     bool validIPv6(string& block) {
71         if (block.size() > 0 && block.size() <= 4) {
72             for (int i = 0; i < block.size(); i++) {
73                 char c = block[i];
74                 if (validIPv6Chars.find(c) == string::npos)
75                     return false;
76             }
77             return true;
78         }
79         return false;
80     }
81 };
View Code

 


520. Detect Capital (easy)

判断单词的大小写是否符合格式

Given a word, you need to judge whether the usage of capitals in it is right or not.

We define the usage of capitals in a word to be right when one of the following cases holds:

All letters in this word are capitals, like "USA".
All letters in this word are not capitals, like "leetcode".
Only the first letter in this word is capital if it has more than one letter, like "Google".
Otherwise, we define that this word doesn't use capitals in a right way.
Example 1:
Input: "USA"
Output: True
Example 2:
Input: "FlaG"
Output: False
Note: The input will be a non-empty word consisting of uppercase and lowercase latin letters.
problem
 1 class Solution {
 2 public:
 3     bool detectCapitalUse(string word) {
 4         if (word.size() <= 1)
 5             return true;
 6         bool lable = isCapital(word[0]) && isCapital(word[1]);
 7         for (int i = 1; i < word.size(); ++i) {
 8             if (isCapital(word[i]) != lable)
 9                 return false;
10         }
11         return true;
12     }
13     bool isCapital(char c) {
14         return c >= 'A' && c <= 'Z';
15     }
16 };
View Code

 


521. Longest Uncommon Subsequence I (easy)

两个字符串,求最长的一个字符串:是其中一个的子串,但不是另一个的子串。

Given a group of two strings, you need to find the longest uncommon subsequence of this group of two strings. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings.

A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string.

The input will be two strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1.

Example 1:
Input: "aba", "cdc"
Output: 3
Explanation: The longest uncommon subsequence is "aba" (or "cdc"), 
because "aba" is a subsequence of "aba", 
but not a subsequence of any other strings in the group of two strings. 
Note:

Both strings' lengths will not exceed 100.
Only letters from a ~ z will appear in input strings.
problem
1 class Solution {
2 public:
3     int findLUSlength(string a, string b) {
4         return a == b ? -1 : max(a.size(), b.size());
5     }
6 };
View Code

 


522. Longest Uncommon Subsequence II (medium) #

多个字符串,求最长的一个字符串:是其中一个的子串,但不是其他的子串。

Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings.

A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string.

The input will be a list of strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1.

Example 1:
Input: "aba", "cdc", "eae"
Output: 3
Note:

All the given strings' lengths will not exceed 10.
The length of the given list will be in the range of [2, 50].
problem
 1 class Solution {
 2 public:
 3     int findLUSlength(vector<string>& strs) {
 4         map<int, vector<string>> mp;
 5         unordered_set<string> seqs;
 6         bool first = true;
 7         for (auto str : strs)
 8             mp[str.size()].push_back(str);
 9         for (auto ptr = mp.rbegin(); ptr != mp.rend(); ++ptr) {
10             auto& strVec = ptr -> second;
11             for (string str : strVec) {
12                 if (count(strVec.begin(), strVec.end(), str) > 1 || findSet(str, seqs))
13                     seqs.insert(str);
14                 else
15                     return ptr -> first;
16             }
17         }
18         return -1;
19     }
20     bool isSubseq(string s1, string s2) {
21         int i = 0;
22         for (char c : s2) {
23             if (s1[i] == c)
24                 ++i;
25         }
26         return i == s1.size();
27     }
28     bool findSet(string s, unordered_set<string>& seqs) {
29         for (string seq : seqs) {
30             if (isSubseq(s, seq))
31                 return true;
32         }
33         return false;
34     }
35 };
View Code

 使用lambda表达式和bind函数

 1 class Solution {
 2 public:
 3     int findLUSlength(vector<string>& strs) {
 4         map<int, vector<string>> mp;
 5         unordered_set<string> seqs;
 6         auto isSubseq = [](string s1, string s2) {
 7             int i = 0;
 8             for (char c : s2) {
 9                 if (s1[i] == c)
10                     ++i;
11             }
12             return i == s1.size();
13         };
14         bool first = true;
15         for (auto str : strs)
16             mp[str.size()].push_back(str);
17         for (auto ptr = mp.rbegin(); ptr != mp.rend(); ++ptr) {
18             auto& strVec = ptr -> second;
19             for (string str : strVec) {
20                 if (count(strVec.begin(), strVec.end(), str) > 1 || \
21                     find_if(seqs.begin(), seqs.end(), bind(isSubseq, str, std::placeholders::_1)) != seqs.end())
22                     seqs.insert(str);
23                 else
24                     return ptr -> first;
25             }
26         }
27         return -1;
28     }
29 };
View Code

 


537. Complex Number Multiplication (medium)

复数表达式相乘

Given two strings representing two complex numbers.

You need to return a string representing their multiplication. Note i2 = -1 according to the definition.

Example 1:
Input: "1+1i", "1+1i"
Output: "0+2i"
Explanation: (1 + i) * (1 + i) = 1 + i2 + 2 * i = 2i, and you need convert it to the form of 0+2i.
Example 2:
Input: "1+-1i", "1+-1i"
Output: "0+-2i"
Explanation: (1 - i) * (1 - i) = 1 + i2 - 2 * i = -2i, and you need convert it to the form of 0+-2i.
Note:

The input strings will not have extra blank.
The input strings will be given in the form of a+bi, where the integer a and b will both belong to the range of [-100, 100]. And the output should be also in this form.
problem
 1 class Solution {
 2 public:
 3     string complexNumberMultiply(string a, string b) {
 4         auto aPair = parse(a);
 5         auto bPair = parse(b);
 6         int m = aPair.first*bPair.first - aPair.second*bPair.second;
 7         int n = aPair.first*bPair.second + aPair.second*bPair.first;
 8         return to_string(m) + "+" + to_string(n) + "i";
 9     }
10     pair<int, int> parse(string s) {
11         int plusIndex = find_if(s.begin(), s.end(), [] (char c) {return c == '+';}) - s.begin();
12         int a = stoi(s.substr(0, plusIndex + 1));
13         int b = stoi(s.substr(plusIndex + 1));
14         return {a, b};
15     }
16 };
View Code

使用stringstream

 1 class Solution {
 2 public:
 3     string complexNumberMultiply(string a, string b) {
 4         int ra, ia, rb, ib;
 5         char buff;
 6         stringstream aa(a), bb(b), ans;
 7         aa >> ra >> buff >> ia >> buff;
 8         bb >> rb >> buff >> ib >> buff;
 9         ans << ra*rb - ia*ib << "+" << ra*ib + rb*ia << "i";
10         return ans.str();
11     }
12 };
View Code

 


539. Minimum Time Difference (medium)

所有列出时间之间的最小时间差

Given a list of 24-hour clock time points in "Hour:Minutes" format, find the minimum minutes difference between any two time points in the list.
Example 1:
Input: ["23:59","00:00"]
Output: 1
Note:
The number of time points in the given list is at least 2 and won't exceed 20000.
The input time is legal and ranges from 00:00 to 23:59.
problem
 1 class Solution {
 2 public:
 3     int findMinDifference(vector<string>& timePoints) {
 4         vector<bool> mark(60*24, false);
 5         int minTime = INT_MAX, maxTime = -60*24, res = INT_MAX;
 6         for (string timePoint : timePoints) {
 7             int time = stoi(timePoint.substr(0, 2))*60 + stoi(timePoint.substr(3));
 8             if (mark[time])
 9                 return 0;
10             mark[time] = true;
11         }
12         for (int i = 0; i < 60*24; ++i) {
13             if (!mark[i])
14                 continue;
15             if (minTime == INT_MAX)
16                 minTime = i;
17             res = min(res, i - maxTime);
18             maxTime = i;
19         }
20         return min(res, 60*24 + minTime - maxTime);
21     }
22 };
View Code

 


541. Reverse String II (easy)

翻转字符串,隔k个翻转k个

Given a string and an integer k, you need to reverse the first k characters for every 2k characters counting from the start of the string. If there are less than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original.
Example:
Input: s = "abcdefg", k = 2
Output: "bacdfeg"
Restrictions:
The string consists of lower English letters only.
Length of the given string and k will in the range [1, 10000]
problem
 1 class Solution {
 2 public:
 3     string reverseStr(string s, int k) {
 4         int i = 0;
 5         while (i < s.size()) {
 6             if (i + k >= s.size())
 7                 reverse(s.begin() + i, s.end());
 8             else
 9                 reverse(s.begin() + i, s.begin() + i + k);
10             i += k + k;
11         }
12         return s;
13     }
14 };
View Code

 


551. Student Attendance Record I (easy)

学生考勤

You are given a string representing an attendance record for a student. The record only contains the following three characters:
'A' : Absent.
'L' : Late.
'P' : Present.
A student could be rewarded if his attendance record doesn't contain more than one 'A' (absent) or more than two continuous 'L' (late).

You need to return whether the student could be rewarded according to his attendance record.

Example 1:
Input: "PPALLP"
Output: True
Example 2:
Input: "PPALLL"
Output: False
problem
 1 class Solution {
 2 public:
 3     bool checkRecord(string s) {
 4         int cntA = 0, cntL = 0;
 5         for (char c : s) {
 6             if (c == 'L')
 7                 ++cntL;
 8             else
 9                 cntL = 0;
10             if (c == 'A')
11                 ++cntA;
12             if (cntL > 2 || cntA > 1)
13                 return false;
14         }
15         return true;
16     }
17 };
View Code

 


553. Optimal Division (medium)

连除表达式加括号,使结果最大

Given a list of positive integers, the adjacent integers will perform the float division. For example, [2,3,4] -> 2 / 3 / 4.

However, you can add any number of parenthesis at any position to change the priority of operations. You should find out how to add parenthesis to get the maximum result, and return the corresponding expression in string format. Your expression should NOT contain redundant parenthesis.

Example:
Input: [1000,100,10,2]
Output: "1000/(100/10/2)"
Explanation:
1000/(100/10/2) = 1000/((100/10)/2) = 200
However, the bold parenthesis in "1000/((100/10)/2)" are redundant, 
since they don't influence the operation priority. So you should return "1000/(100/10/2)". 

Other cases:
1000/(100/10)/2 = 50
1000/(100/(10/2)) = 50
1000/100/10/2 = 0.5
1000/100/(10/2) = 2
Note:

The length of the input array is [1, 10].
Elements in the given array will be in range [2, 1000].
There is only one optimal division for each test case.
problem
 1 class Solution {
 2 public:
 3     string optimalDivision(vector<int>& nums) {
 4         if (nums.size() == 1)
 5             return to_string(nums[0]);
 6         if (nums.size() == 2)
 7             return to_string(nums[0]) + "/" + to_string(nums[1]);
 8         string res = to_string(nums[0]) + "/(" + to_string(nums[1]);
 9         for (int i = 2; i < nums.size(); ++i)
10             res += "/" + to_string(nums[i]);
11         return res + ")";
12     }
13 };
View Code

 


556. Next Greater Element III (medium)

下一个更大的数,输入是int

Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly the same digits existing in the integer n and is greater in value than n. If no such positive 32-bit integer exists, you need to return -1.

Example 1:

Input: 12
Output: 21
 

Example 2:

Input: 21
Output: -1
problem
 1 class Solution {
 2 public:
 3     int nextGreaterElement(int n) {
 4         string str = to_string(n);
 5         int i = str.size() - 1, j = i;
 6         for (; i > 0 && str[i - 1] >= str[i]; --i);
 7         if (i == 0)
 8             return -1;
 9         for (--i; str[j] <= str[i]; --j);
10         swap(str[i], str[j]);
11         sort(str.begin() + i + 1, str.end());
12         long long res = stoll(str);
13         return res > INT_MAX ? -1 : res;
14     }
15 };
View Code

 


557. Reverse Words in a String III (easy)

翻转字符串中的每个单词

Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order.

Example 1:
Input: "Let's take LeetCode contest"
Output: "s'teL ekat edoCteeL tsetnoc"
Note: In the string, each word is separated by single space and there will not be any extra space in the string.
problem
 1 class Solution {
 2 public:
 3     string reverseWords(string s) {
 4         for (int i = 0, j = 0; i <= s.size(); ++i) {
 5             if (i == s.size() || s[i] == ' ') {
 6                 reverse(s.begin() + j, s.begin() + i);
 7                 j = i + 1;
 8             }
 9         }
10         return s;
11     }
12 };
View Code

 


564. Find the Closest Palindrome (hard) # X

找到距离n最近的回文数

Given an integer n, find the closest integer (not including itself), which is a palindrome.

The 'closest' is defined as absolute difference minimized between two integers.

Example 1:
Input: "123"
Output: "121"
Note:
The input n is a positive integer represented by string, whose length will not exceed 18.
If there is a tie, return the smaller one as answer.
problem
 1 // 思路:取出数字的前一半,加-1,0,1,再和他的翻转组成回文
 2 // 1:数字很大,需要stll
 3 // 2:空字符串无法调用stll,需要单独处理10以下的数
 4 // 3:如果共有奇数为,组合成回文时要去掉中间位
 5 // 3:不能和原数字相同,所以999中99+1=100,组成10001;100中10-1=9,去掉中间为,最后为9.因此单独处理99..99和10..0的数
 6 class Solution {
 7 public:
 8     string nearestPalindromic(string n) {
 9         int length = n.size();
10         long long numN = stoll(n);
11         if (numN <= 10)
12             return to_string(numN - 1);
13         long long res = 0, delta = INT_MAX, prefix = stoll(n.substr(0, (length + 1)/2));
14         vector<long long> items;
15         for (int i = length; i >= length - 1; --i) {
16             for (int j = 1; j >= -1; j -= 2)
17                 items.push_back(pow(10, i) + j);
18         }
19         for (long long i = prefix - 1; i <= prefix + 1; ++i) {
20             string tmp = toPalindrome(to_string(i), length%2);
21             items.push_back(stoll(tmp));
22         }
23         for (auto num : items) {
24             long long deltaNum = abs(num - numN);
25             if ((deltaNum != 0) && (deltaNum < delta || (deltaNum == delta && num < res))) {
26                 res = num;
27                 delta = deltaNum;
28             }
29         }
30         return to_string(res);
31     }
32     string toPalindrome(string s, bool odd) {
33         string cp(s);
34         reverse(cp.begin(), cp.end());
35         return odd ? s + cp.substr(1) : s + cp;
36     }
37 };
View Code

 


583. Delete Operation for Two Strings (medium)

两个字符串总共去掉多少个字符可以使他们相同

Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string.

Example 1:
Input: "sea", "eat"
Output: 2
Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".
Note:
The length of given words won't exceed 500.
Characters in given words can only be lower-case letters.
problem
 1 class Solution {
 2 public:
 3     int minDistance(string word1, string word2) {
 4         int m = word1.size(), n = word2.size();
 5         vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
 6         for (int i = 1; i <= m; ++i) {
 7             for (int j = 1; j <= n; ++j) {
 8                 if (word1[i - 1] == word2[j - 1])
 9                     dp[i][j] = dp[i - 1][j - 1] + 1;
10                 else
11                     dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
12             }
13         }
14         return m + n - 2*dp[m][n];
15     }
16 };
View Code

 


591. Tag Validator (hard)

太长,没看!

Given a string representing a code snippet, you need to implement a tag validator to parse the code and return whether it is valid. A code snippet is valid if all the following rules hold:

The code must be wrapped in a valid closed tag. Otherwise, the code is invalid.
A closed tag (not necessarily valid) has exactly the following format : <TAG_NAME>TAG_CONTENT</TAG_NAME>. Among them, <TAG_NAME> is the start tag, and </TAG_NAME> is the end tag. The TAG_NAME in start and end tags should be the same. A closed tag is valid if and only if the TAG_NAME and TAG_CONTENT are valid.
A valid TAG_NAME only contain upper-case letters, and has length in range [1,9]. Otherwise, the TAG_NAME is invalid.
A valid TAG_CONTENT may contain other valid closed tags, cdata and any characters (see note1) EXCEPT unmatched <, unmatched start and end tag, and unmatched or closed tags with invalid TAG_NAME. Otherwise, the TAG_CONTENT is invalid.
A start tag is unmatched if no end tag exists with the same TAG_NAME, and vice versa. However, you also need to consider the issue of unbalanced when tags are nested.
A < is unmatched if you cannot find a subsequent >. And when you find a < or </, all the subsequent characters until the next > should be parsed as TAG_NAME (not necessarily valid).
The cdata has the following format : <![CDATA[CDATA_CONTENT]]>. The range of CDATA_CONTENT is defined as the characters between <![CDATA[ and the first subsequent ]]>.
CDATA_CONTENT may contain any characters. The function of cdata is to forbid the validator to parse CDATA_CONTENT, so even it has some characters that can be parsed as tag (no matter valid or invalid), you should treat it as regular characters.
Valid Code Examples:
Input: "<DIV>This is the first line <![CDATA[<div>]]></DIV>"

Output: True

Explanation: 

The code is wrapped in a closed tag : <DIV> and </DIV>. 

The TAG_NAME is valid, the TAG_CONTENT consists of some characters and cdata. 

Although CDATA_CONTENT has unmatched start tag with invalid TAG_NAME, it should be considered as plain text, not parsed as tag.

So TAG_CONTENT is valid, and then the code is valid. Thus return true.


Input: "<DIV>>>  ![cdata[]] <![CDATA[<div>]>]]>]]>>]</DIV>"

Output: True

Explanation:

We first separate the code into : start_tag|tag_content|end_tag.

start_tag -> "<DIV>"

end_tag -> "</DIV>"

tag_content could also be separated into : text1|cdata|text2.

text1 -> ">>  ![cdata[]] "

cdata -> "<![CDATA[<div>]>]]>", where the CDATA_CONTENT is "<div>]>"

text2 -> "]]>>]"


The reason why start_tag is NOT "<DIV>>>" is because of the rule 6.
The reason why cdata is NOT "<![CDATA[<div>]>]]>]]>" is because of the rule 7.
Invalid Code Examples:
Input: "<A>  <B> </A>   </B>"
Output: False
Explanation: Unbalanced. If "<A>" is closed, then "<B>" must be unmatched, and vice versa.

Input: "<DIV>  div tag is not closed  <DIV>"
Output: False

Input: "<DIV>  unmatched <  </DIV>"
Output: False

Input: "<DIV> closed tags with invalid tag name  <b>123</b> </DIV>"
Output: False

Input: "<DIV> unmatched tags with invalid tag name  </1234567890> and <CDATA[[]]>  </DIV>"
Output: False

Input: "<DIV>  unmatched start tag <B>  and unmatched end tag </C>  </DIV>"
Output: False
Note:
For simplicity, you could assume the input code (including the any characters mentioned above) only contain letters, digits, '<','>','/','!','[',']' and ' '.
problem

 


606. Construct String from Binary Tree (easy)

把二叉树转换为()描述的字符串

You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way.

The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree.

Example 1:
Input: Binary tree: [1,2,3,4]
       1
     /   \
    2     3
   /    
  4     

Output: "1(2(4))(3)"

Explanation: Originallay it needs to be "1(2(4)())(3()())", 
but you need to omit all the unnecessary empty parenthesis pairs. 
And it will be "1(2(4))(3)".
Example 2:
Input: Binary tree: [1,2,3,null,4]
       1
     /   \
    2     3
     \  
      4 

Output: "1(2()(4))(3)"

Explanation: Almost the same as the first example, 
except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output.
problem
 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     string tree2str(TreeNode* t) {
13         if (t == NULL)
14             return "";
15         if (t -> left == NULL && t -> right == NULL)
16             return to_string(t -> val);
17         else if (t -> right)
18             return to_string(t -> val) + "(" + tree2str(t -> left) + ")(" + tree2str(t -> right) + ")";
19         else
20             return to_string(t -> val) + "(" + tree2str(t -> left) + ")";
21     }
22 };
View Code

 


609. Find Duplicate File in System (medium)

把内容相同的文件合并到一起

(使用stringstream)

Given a list of directory info including directory path, and all the files with contents in this directory, you need to find out all the groups of duplicate files in the file system in terms of their paths.

A group of duplicate files consists of at least two files that have exactly the same content.

A single directory info string in the input list has the following format:

"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"

It means there are n files (f1.txt, f2.txt ... fn.txt with content f1_content, f2_content ... fn_content, respectively) in directory root/d1/d2/.../dm. Note that n >= 1 and m >= 0. If m = 0, it means the directory is just the root directory.

The output is a list of group of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format:

"directory_path/file_name.txt"

Example 1:
Input:
["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"]
Output:  
[["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]
Note:
No order is required for the final output.
You may assume the directory name, file name and file content only has letters and digits, and the length of file content is in the range of [1,50].
The number of files given is in the range of [1,20000].
You may assume no files or directories share the same name in the same directory.
You may assume each given directory info represents a unique directory. Directory path and file info are separated by a single blank space.
Follow-up beyond contest:
Imagine you are given a real file system, how will you search files? DFS or BFS?
If the file content is very large (GB level), how will you modify your solution?
If you can only read the file by 1kb each time, how will you modify your solution?
What is the time complexity of your modified solution? What is the most time-consuming part and memory consuming part of it? How to optimize?
How to make sure the duplicated files you find are not false positive?
problem
 1 class Solution {
 2 public:
 3     vector<vector<string>> findDuplicate(vector<string>& paths) {
 4         unordered_map<string, vector<string>> mp;
 5         for (string path : paths) {
 6             stringstream ss(path);
 7             string dir, s;
 8             getline(ss, dir, ' ');
 9             while (getline(ss, s, ' ')) {
10                 int left = s.find('('), right = s.find(')');
11                 string fileName = s.substr(0, left);
12                 string content = s.substr(left + 1, right - left - 1);
13                 mp[content].push_back(dir + "/" + fileName);
14             }
15         }
16         vector<vector<string>> res;
17         for (auto m : mp)
18             if (m.second.size() > 1)
19                 res.push_back(m.second);
20         return res;
21     }
22 };
View Code

 


632. Smallest Range (hard) #

包含所有数组中至少一个元素的最小区间

You have k lists of sorted integers in ascending order. Find the smallest range that includes at least one number from each of the k lists.

We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c.

Example 1:
Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
Output: [20,24]
Explanation: 
List 1: [4, 10, 15, 24,26], 24 is in range [20,24].
List 2: [0, 9, 12, 20], 20 is in range [20,24].
List 3: [5, 18, 22, 30], 22 is in range [20,24].
Note:
The given list may contain duplicates, so ascending order means >= here.
1 <= k <= 3500
-105 <= value of elements <= 105.
For Java users, please note that the input type has been changed to List<List<Integer>>. And after you reset the code template, you'll see this point.
problem
 1 // 类似k个归并排序,priority_queue中包含所有数组中的元素,只需要每次判断最大值和最小值之间的差是不是最小。
 2 // 重载运算符必须用struct,最小堆要用大于号。
 3 struct smaller {
 4     bool operator()(pair<int, int>& a, pair<int, int>& b) {
 5         return a.first > b.first;
 6     }
 7 };
 8 
 9 class Solution {
10 public:
11     vector<int> smallestRange(vector<vector<int>>& nums) {
12         int m = nums.size(), pqMax = INT_MIN;
13         priority_queue<pair<int, int>, vector<pair<int, int>>, smaller> pq;
14         vector<int> index(m, 1);
15         for (int i = 0; i < m; ++i) {
16             pq.push({nums[i][0], i});
17             pqMax = max(pqMax, nums[i][0]);
18         }
19         vector<int> res = {pq.top().first, pqMax};
20         int size = res[1] - res[0];
21         while (1) {
22             int k = pq.top().second;
23             pq.pop();
24             if (index[k] == nums[k].size())
25                 return res;
26             pqMax = max(pqMax, nums[k][index[k]]);
27             pq.push({nums[k][index[k]++], k});
28             if (pqMax - pq.top().first < size) {
29                 size = pqMax - pq.top().first;
30                 res = {pq.top().first, pqMax};
31             }
32         }
33         return res;
34     }
35 };
View Code

 


635. Design Log Storage System (medium)

设计log存储系统

You are given several logs that each log contains a unique id and timestamp. Timestamp is a string that has the following format: Year:Month:Day:Hour:Minute:Second, for example, 2017:01:01:23:59:59. All domains are zero-padded decimal numbers.

Design a log storage system to implement the following functions:

void Put(int id, string timestamp): Given a log's unique id and timestamp, store the log in your storage system.

int[] Retrieve(String start, String end, String granularity): Return the id of logs whose timestamps are within the range from start to end. Start and end all have the same format as timestamp. However, granularity means the time level for consideration. For example, start = "2017:01:01:23:59:59", end = "2017:01:02:23:59:59", granularity = "Day", it means that we need to find the logs within the range from Jan. 1st 2017 to Jan. 2nd 2017.

Example 1:
put(1, "2017:01:01:23:59:59");
put(2, "2017:01:01:22:59:59");
put(3, "2016:01:01:00:00:00");
retrieve("2016:01:01:01:01:01","2017:01:01:23:00:00","Year"); // return [1,2,3], because you need to return all logs within 2016 and 2017.
retrieve("2016:01:01:01:01:01","2017:01:01:23:00:00","Hour"); // return [1,2], because you need to return all logs start from 2016:01:01:01 to 2017:01:01:23, where log 3 is left outside the range.
Note:
There will be at most 300 operations of Put or Retrieve.
Year ranges from [2000,2017]. Hour ranges from [00,23].
Output for Retrieve has no order required.
problem
 1 #include <string>
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <vector>
 5 #include <math.h> 
 6 #include <numeric>
 7 #include <unordered_map>
 8 using namespace std;
 9 
10 
11 class LogSystem {
12 public:
13     LogSystem() {
14         
15     }
16     
17     void put(int id, string timestamp) {
18         storage[id] = put_vector(timestamp);
19     }
20     
21     vector<int> retrieve(string s, string e, string gra) {
22         vector<int> res;
23         vector<string> start = put_vector(s);
24         vector<string> end = put_vector(e);
25         int granularity;
26         if (gra == "Year") granularity = 1;
27         else if (gra == "Month") granularity = 2;
28         else if (gra == "Day") granularity = 3;
29         else if (gra == "Hour") granularity = 4;
30         else if (gra == "Minute") granularity = 5;
31         else if (gra == "Second") granularity = 6;
32         for (auto st : storage) {
33             bool pass = true;
34             for (int i = 0; i < granularity; ++i) {
35                 if (st.second[i] != start[i]) {
36                     pass = st.second[i] > start[i];
37                     break;
38                 }
39             }
40             for (int i = 0; pass == true && i < granularity; ++i) {
41                 if (st.second[i] != end[i]) {
42                     pass = st.second[i] < end[i];
43                     break;
44                 }
45             }
46             if (pass == true) res.push_back(st.first);
47         }
48         return res;
49     }
50 
51     vector<string> put_vector(string& timestamp) {
52         vector<string> v(6);
53         stringstream ss(timestamp);
54         for (int i = 0; i < 6; ++i)
55             getline(ss, v[i], ':');
56         return v;
57     }
58 
59 private:
60     unordered_map<int, vector<string>> storage;
61 };
62 
63 /**
64  * Your LogSystem object will be instantiated and called as such:
65  * LogSystem obj = new LogSystem();
66  * obj.put(id,timestamp);
67  * vector<int> param_2 = obj.retrieve(s,e,gra);
68  */
69 
70 int main(int argc, char const *argv[])
71 {
72     LogSystem ss;
73     ss.put(4, "2004:10:25:13:49:48");
74     ss.put(6, "2004:10:04:21:49:49");
75     ss.put(10, "2005:01:17:23:36:39");
76     vector<int> test = ss.retrieve("2004:09:23:19:31:46", "2005:10:27:16:51:21", "Year");
77     cout << test[0] << endl;
78     return 0;
79 }
View Code

 


647. Palindromic Substrings (medium)

 子串中有多少是回文的。

Given a string, your task is to count how many palindromic substrings in this string.

The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

Example 1:
Input: "abc"
Output: 3
Explanation: Three palindromic strings: "a", "b", "c".
Example 2:
Input: "aaa"
Output: 6
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".
Note:
The input string length won't exceed 1000.
problem
 1 class Solution {
 2 public:
 3     int countSubstrings(string s) {
 4         int res = 0;
 5         for (int i = 0; i < s.size(); ++i) {
 6             valid(s, i, i, res);
 7             valid(s, i, i + 1, res);
 8         }
 9         return res;
10     }
11     void valid(string& s, int i, int j, int& cnt) {
12         while (i >= 0 && j < s.size() && s[i] == s[j]) {
13             ++cnt;
14             --i;
15             ++j;
16         }
17     }
18 };
View Code

 


657. Judge Route Circle (easy)

判断机器人是否走回到原点

Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot makes a circle, which means it moves back to the original place.

The move sequence is represented by a string. And each move is represent by a character. The valid robot moves are R (Right), L (Left), U (Up) and D (down). The output should be true or false representing whether the robot makes a circle.

Example 1:
Input: "UD"
Output: true
Example 2:
Input: "LL"
Output: false
problem
 1 class Solution {
 2 public:
 3     bool judgeCircle(string moves) {
 4         int U = 0, L = 0;
 5         for (char move : moves) {
 6             if (move == 'U')
 7                 ++U;
 8             else if (move == 'D')
 9                 --U;
10             else if (move == 'L')
11                 ++L;
12             else if (move == 'R')
13                 --L;
14         }
15         return U == 0 && L == 0;
16     }
17 };
View Code

 


678. Valid Parenthesis String (medium) #

判断string中的小括号是否匹配,'*'可以代表任意一个或空。

Given a string containing only three types of characters: '(', ')' and '*', write a function to check whether this string is valid. We define the validity of a string by these rules:

Any left parenthesis '(' must have a corresponding right parenthesis ')'.
Any right parenthesis ')' must have a corresponding left parenthesis '('.
Left parenthesis '(' must go before the corresponding right parenthesis ')'.
'*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string.
An empty string is also valid.
Example 1:
Input: "()"
Output: True
Example 2:
Input: "(*)"
Output: True
Example 3:
Input: "(*))"
Output: True
Note:
The string size will be in the range [1, 100].
problem
 1 // 左括号计数不再是一个值,而是一个范围
 2 class Solution {
 3 public:
 4     bool checkValidString(string s) {
 5         int lower = 0, upper = 0;
 6         for (char c : s) {
 7             if (c=='(') {
 8                 lower++;
 9                 upper++;
10             }
11             else if (c==')') {
12                 lower--;               
13                 upper--;
14             }
15             else { // * encountered
16                 lower--;
17                 upper++;
18             }
19             lower = max(lower, 0);
20             if (upper<0) // unmatched ')' found in the middle of string
21                 return false;
22         }
23         return lower==0;
24     }
25 };
View Code
 1 // left和star分别记录'('和'*'的个数,最后比较'('和'*'的个数;
 2 // 但存在'('在'*'右边的情况,因此用cnt记录'('和'*'后面的'('的个数。
 3 class Solution {
 4 public:
 5     bool checkValidString(string s) {
 6         int left = 0, star = 0, cnt = 0;
 7         for (char c : s) {
 8             if (c == '('){
 9                 if (left == 0)
10                     star = 0;
11                 ++left;
12             }
13             else if (c == ')') {
14                 if (left > 0)
15                     --left;
16                 else if (star > 0)
17                     --star;
18                 else
19                     return false;
20             }
21             else
22                 ++star;
23             cnt = c == '(' ? cnt + 1 : cnt - 1;
24             cnt = max(cnt, 0);
25         }
26         return star >= left && cnt == 0;
27     }
28 };
View Code

 


680. Valid Palindrome II (easy)

允许删除最多一个字母,判断string是否是回文

Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.

Example 1:
Input: "aba"
Output: True
Example 2:
Input: "abca"
Output: True
Explanation: You could delete the character 'c'.
Note:
The string will only contain lowercase characters a-z. The maximum length of the string is 50000.
problem
 1 class Solution {
 2 public:
 3     bool validPalindrome(string s) {
 4         for (int i = 0, j = s.size() - 1; i < j; ++i, --j) {
 5             if (s[i] != s[j])
 6                 return valid(s, i + 1, j) || valid(s, i, j - 1);
 7         }
 8         return true;
 9     }
10     bool valid(string s, int i, int j) {
11         while (i < j) {
12             if (s[i++] != s[j--])
13                 return false;
14         }
15         return true;
16     }
17 };
View Code

 


696. Count Binary Substrings (easy)

0和1的个数相同的子串个数,(0或1必须连续)

Give a string s, count the number of non-empty (contiguous) substrings that have the same number of 0's and 1's, and all the 0's and all the 1's in these substrings are grouped consecutively.

Substrings that occur multiple times are counted the number of times they occur.

Example 1:
Input: "00110011"
Output: 6
Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01".

Notice that some of these substrings repeat and are counted the number of times they occur.

Also, "00110011" is not a valid substring because all the 0's (and 1's) are not grouped together.
Example 2:
Input: "10101"
Output: 4
Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.
Note:

s.length will be between 1 and 50,000.
s will only consist of "0" or "1" characters.
problem
 1 class Solution {
 2 public:
 3     int countBinarySubstrings(string s) {
 4         int cnt1 = 1, cnt2 = 0, res = 0;
 5         for (int i = 0; i < s.size(); ++i) {
 6             for (char c = s[i]; i + 1 < s.size() && c == s[i + 1]; ++i)
 7                 ++cnt1;
 8             res += min(cnt1, cnt2);
 9             cnt2 = cnt1;
10             cnt1 = 1;
11         }
12         return res;
13     }
14 };
View Code

 

 

 

 

 

p

posted @ 2018-02-01 09:49  zz091207  阅读(248)  评论(0编辑  收藏  举报