# 基础知识：

### 【面试题49：把字符串转换成整数】String to Integer (atoi)

I think we only need to handle four cases:
sign of the number
overflow
invalid input

### 【面试题04：替换空格】

``````class Solution {
public:
void replaceSpace(char *str,int length) {
int count=0;
int strlength =0;
int i =0 ;
while(str[i] != '\0'){
if (str[i] == ' ' )
count++;
strlength ++;
i++;
}
int newlength = strlength + 2*count;
int p1 = strlength;
int p2 = newlength;
while( p1 >= 0 && p2>p1){
if( str[p1--] == ' '){
str[p2--] = '0';  str[p2--] = '2'; str[p2--] = '%';
}
else
str[p2--] = str[p1--];
}
}
};
``````

### 【面试题53：正则表达式匹配】Regular Expression Matching

``````class Solution {
public:
bool isMatch(string s, string p) {
/*
if 第二个字符为‘*’
if 第一个字符相等
三种情况
else
Match(sPos,pPos+2,s,p);
else
if 第一个字符相等
Match(sPos+1,pPos+1,s,p);
else
false
*/
return Match(0,0,s,p);
}
bool Match(int sPos, int pPos, string &s, string &p) {
//s结束，p结束，返回true
if(sPos >= s.length() && pPos >= p.length())
return true;
//s未结束，p结束，返回false
if(sPos < s.length() && pPos >= p.length())
return false;
//p未结束，不管s结束没，都有可能匹配成功
if(pPos+1 < p.length() && p[pPos+1] == '*'){
if(sPos<s.length() && (s[sPos] == p[pPos] || p[pPos] == '.'))
return Match(sPos,pPos+2,s,p)
||Match(sPos+1,pPos+2,s,p)
||Match(sPos+1,pPos,s,p);
else
return Match(sPos,pPos+2,s,p);
}
if(sPos<s.length() && (s[sPos] == p[pPos] || p[pPos] == '.'))
return Match(sPos+1,pPos+1,s,p);
return false;
}
};
``````

### 【面试题54：表示数值的字符串】

``````class Solution {
public:
bool isNumber(string s) {
if(s.empty())
return false;
int pos = 0;
//" 0.1 " => true，开头空格情况
while(pos<s.length() && s[pos] == ' ')
pos++;
bool result = isInt(s,pos);
if(pos<s.length() && s[pos] == '.'){
if(++pos<s.length())
result = isUnsignedInt(s,pos) || result;
else
return result;
}
if(pos<s.length() && (s[pos] == 'e' || s[pos] =='E')){
if(++pos<s.length())
result = isInt(s,pos) && result;
else
return false;
}
//“1  ” =>true，结尾空格情况
while(pos<s.length() && s[pos] == ' ')
pos++;
return result && (pos == s.length());
}

bool isInt(string &s, int &pos){
if(s[pos] == '+' || s[pos] == '-')
pos++;
return isUnsignedInt(s,pos);
}

bool isUnsignedInt(string &s, int &pos){
bool result = false;
while(pos<s.length() && (s[pos]>='0' && s[pos]<='9')){
pos++;
result = true;
}
return result;
}
};
``````

### 【面试题28：字符串的排列】

``````class Solution {
public:
vector<string> Permutation(string str) {
vector<string>result;
if(str.empty())
return {};
Permutation(str,0,result);
//从小到大排序
sort(result.begin(), result.end());
return result;
}
void Permutation(string &str, int pos, vector<string> &result){
//当遍历到最后一个字符是输出；类似于树的叶节点。
//不同问题不同条件，如最短路径，统计路径小于最短，则更新路径；
if(pos == str.length()-1)
result.push_back(str);
//循环接下来所有字符，类似多叉树，二叉树，只需循环左右子树。
//当一次遍历到叶节点时，要回溯，需要swap回来，类似回到父节点，然后到下个叶节点。
for(int i=pos; i<str.length();i++){
if( pos == i || str[pos] != str[i]){
swap(str[pos],str[i]);
Permutation(str,pos+1,result);
swap(str[i],str[pos]); //返回父节点，恢复当一次交换
}
}

}
};
``````

### 【面试题46：把数字翻译成字符串】 Decode Ways

``````//来自leetcode，0没有对应的码子，只有10和20能翻译
class Solution {
public:
int numDecodings(string s) {
if(s.empty())
return 0;
int* counts = new int[s.length()];
if(s[0] == '0') return 0;
counts[0] = 1;

for(int i=1;i<s.length();i++){
int digit1 = s[i] - '0';
int digit2 = s[i-1] -'0';
if(digit1 == 0){
if(digit2 == 1 || digit2 == 2){
counts[i] = (i == 1 ? 1: counts[i-2]);
continue;
}//遇到10或20，counts[i] = counts[i-2]
else
return 0;
}
int coefficient = 0;
int judgeDigit = digit2*10 + digit1;
if(judgeDigit>=10 && judgeDigit<=26)
coefficient = 1;
counts[i] = counts[i-1] + coefficient * ( i == 1 ? 1: counts[i-2]);
}
int result = counts[s.length()-1];
delete[] counts;
return result;

}
};
``````

### 【面试题48：最长不含重复字符的子字符串】

``````class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size() == 0) return 0;
int position[128];
for(int i = 0; i<128;i++)
position[i]=-1;
int curLength = 0;
int maxLength = 0;
for(int i =0; i<s.size();i++){
int prePos = position[s[i]-' '];
if(prePos<0 ||i-prePos>curLength)
curLength++;
else{
curLength = i-prePos;
}
position[s[i]-' ']= i; //更新字符坐标
if(curLength>maxLength)
maxLength = curLength;
}
return maxLength;
}
};
``````

### 【面试题50：第一个只出现一次的字符】First Unique Character in a String

``````class Solution {
public:
int firstUniqChar(string s) {
map<char,int>mapping;
for(int i = 0 ; i< s.size();i++){
mapping[s[i]]++;
}
for(int i = 0; i < s.size(); i++){
if(mapping[s[i]]==1)
return i;
}
return -1;
}
};
``````

# Buddy Strings

``````class Solution {
public:
bool buddyStrings(string A, string B) {
if (A.size() != B.size())  return false;
if(A == B) return isDifferent(A);//如A等于B，若A中有相同字符，即true，否则false；
int pos1 = 0;
while(pos1<A.size() && (A[pos1] == B[pos1]))
pos1++;
int pos2 = pos1+1;
while(pos2<A.size() && (A[pos2] == B[pos2]))
pos2++;
int temp = A[pos1];
A[pos1] = A[pos2];
A[pos2] = temp;
return A==B? true:false;
}
bool isDifferent(string A){
map<char,int>count;
for(int i =0 ; i<A.size();i++){
count[A[i]]++;
if(count[A[i]] >1)
return true;
}
return false;
}
};
``````

# Construct String from Binary Tree

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

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

Example 2: 如无左节点，用null，空().
Input: Binary tree: [1,2,3,null,4]
1
/   \
2     3
\
4

Output: "1(2()(4))(3)"
``````
``````/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
string tree2str(TreeNode* t) {
string res ;
ConstructStr(t,res);
return res;
}
void ConstructStr(TreeNode* t, string &res){
if(!t) return;
res += to_string(t->val);
if(!t->left && !t->right) return;

res += '(';
ConstructStr(t->left,res);
res += ')';

if( !t->right ) return; //若无右子树，则返回。与无左子树不同。
res += '(';
ConstructStr(t->right,res);
res += ')';
}
};
``````

# Roman to Integer

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

``````class Solution {
public:
int romanToInt(string s) {
int sum =0;
map<char,int>mapping={
{'I',1},
{'V',5},
{'X',10},
{'L',50},
{'C',100},
{'D',500},
{'M',1000}
};
for(int i =0; i < s.length()-1; i++){
if(mapping[s[i]]>=mapping[s[i+1]])
sum += mapping[s[i]];
else
sum -= mapping[s[i]];
}
sum += mapping[s[s.length()-1]];
return sum;
}
};
``````

# Valid Parentheses

[],{},(),成对出现，采用栈的数据结构，先进后出。先进栈的符号之后配对。

``````class Solution {
public:
bool isValid(string s) {
map<char,char>mapping = {{'(',')'},{'{','}'},{'[',']'}};
stack<char>pareStack;
for(int i = 0; i<s.size(); i++){
if(s[i] == '(' || s[i] == '{' ||s[i] == '[')
pareStack.push(s[i]);
else{
if(pareStack.empty())
return false;
if(s[i] != mapping[pareStack.top()])
return false;
pareStack.pop();
}
}
return pareStack.empty();
}
};
``````

The input strings are both non-empty and contains only characters 1 or 0.
Example 2:
Input: a = "1010", b = "1011"
Output: "10101"

``````class Solution {
public:
string addBinary(string a, string b) {
int Pa = a.size()-1;
int Pb = b.size()-1;
int overflow = 0;
while(Pa>= 0 || Pb>= 0){
int aStr = Pa>-1 ? a[Pa]-'0': 0;
int bStr = Pb>-1 ? b[Pb]-'0': 0;
overflow = (aStr+bStr+overflow)/2;
Pa--;Pb--;
}
if(overflow)
}
void changeChars(string &s, int begin, int end){
while(begin<end){
char temp = s[begin];
s[begin] = s[end];
s[end] = temp;
begin++;end--;
}
}
};
``````

# Longest Common Prefix

``````class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (strs.empty()) return "";
string samestr = strs[0];
for (int i =1;i<strs.size();i++){
samestr = JudgeSameStr(samestr, strs[i]);
if(samestr.empty()) return samestr;
}
return samestr;
}
string JudgeSameStr(string str1,string str2){
string samestr ="";
for(int j=0; j<str1.size();j++){
if(j>str2.size()-1 || str1[j]!=str2[j]) return samestr;
samestr += str1[j];
}
return samestr;
}
};
``````

# Reverse Words in a String III

Example 1:
Input: "Let's take LeetCode contest"
Output: "s'teL ekat edoCteeL tsetnoc"

PS：判断word结尾的两种情况，1）空格 ；2）串尾

``````class Solution {
public:
string reverseWords(string s) {
int begin = 0;
int end = 0;
while(end<s.size()){
if(s[end] == ' '){
changeChars(s,begin,--end);
begin = end = end+2;
}
else if(end == s.size()-1){
changeChars(s,begin,end++);
}
else{
end++;
}
}
return s;

}
void changeChars(string &s, int begin, int end){
while(begin<end){
char temp = s[begin];
s[begin] = s[end];
s[end] = temp;
begin++;end--;
}
}
};

void TransStr(string &str, int begin, int end){
if(!str.empty()){
while(begin<end)
swap(str[begin++],str[end--]);
}
}
int main(){
string str;
while(getline(cin,str)){
if(str.empty() || str.length()>100)
return 0;
TransStr(str,0,str.length()-1);
int begin = 0;
int end = 0;
while(end < str.length()){
if(str[begin] == ' '){
begin++;
end++;
}
while(end < str.length() && str[end] != ' ')
end++;
TransStr(str,begin,end-1);
begin = end;
}
for(int i=0; i<str.length();i++)
cout<<str[i];
}
return 0;
}
``````

# Longest Valid Parentheses

``````class Solution {
public:
int longestValidParentheses(string s) {
stack<int>sequence;
int max = 0;
for(int i=0; i<s.size(); i++){
if(s[i] == ')' && !sequence.empty() && s[sequence.top()] == '('){
sequence.pop();
int length = sequence.empty()? i+1: i-sequence.top();
max = std::max(length, max);
}
else
sequence.push(i);
}
return max;
}
};
``````

# Push Dominoes

``````class Solution {
public:
string pushDominoes(string str) {
string changeStr;
for (int i = 0; i<str.length(); i++)
changeStr += ".";
int pos = 0;
int nextRight = -1;
while (pos<str.length()) {
if (str[pos] == 'R') {
if (nextRight == -1)
nextRight = pos;//遇到R且前面没有R
else {
//遇到R且前面有R
for (int i = nextRight; i < pos; i++)
changeStr[i] = 'R';
nextRight = pos;//更新R的位置。
}
}
else if (str[pos] == 'L') {
if (nextRight == -1) {
changePos(changeStr, -1, pos);
}//遇到L且前面没有R状态（这个状态是指可以形成RL区间的，而不是已经右倒状态）
else {
changePos(changeStr, nextRight, pos);
nextRight = -1;
}//遇到L且前面有R状态，形成RL区间
}
pos++;
}
if(nextRight != -1)
changePos(changeStr, nextRight, str.length());
return changeStr;
}

void changePos(string &changeStr, int right, int left) {
int i = left;
while(right<0 && i >= 0 && changeStr[i] == '.') {
changeStr[i--] = 'L';
}//L前面没有R，向前置‘L’一直到非‘.’。
i = right;
while(left >= changeStr.length() && i<changeStr.length()) {
changeStr[i++] = 'R';
}//
if (right >= 0 && left < changeStr.length()) {
int middle = (right + left) / 2;
for (int i = right; i<middle; i++)
changeStr[i] = 'R';
if ((right + left) % 2 == 1)
changeStr[middle] = 'R';
for (int i = middle + 1; i <= left; i++)
changeStr[i] = 'L';
}
}
};
``````

# 华为-简单错误记录

1.记录最多8条错误记录，对相同的错误记录(即文件名称和行号完全匹配)只记录一条，错误计数增加；(文件所在的目录不同，文件名和行号相同也要合并)
2.超过16个字符的文件名称，只记录文件的最后有效16个字符；(如果文件名不同，而只是文件名的后16个字符和行号相同，也不要合并)
3.输入的文件可能带路径，记录文件名称不能带路径

##### 输出描述:

``````示例1
## 输入
## 输出

#include<iostream>
#include<vector>
#include<sstream>
#include<string>
using namespace std;

int str2num(string s)
{
int num;
stringstream ss(s);
ss >> num;
return num;
}
int main() {
string str;
vector<string>filenames;//存放文件名（文件名称和行号）
vector<int>count;//对应文件的数量
while(getline(cin,str)){
if(str.length() == 0)
break;
unsigned int idx = str.rfind('\\');
string filename = str.substr(idx+1);
bool exist = false;//记录文件是否存在
for(int i=0;i<filenames.size();i++){
if(filenames[i] == filename){
count[i]++;
exist = true;
break;
}
}
if(!exist){//如果未出现过，就记录。
filenames.push_back(filename);
count.push_back(1);
}
}
//直接插入排序
for(int i=1; i<=filenames.size(); ++i){
for(int j=i; j > 0; --j){
if(count[j] > count[j -1]){
swap(count[j],count[j-1]);
swap(filenames[j],filenames[j-1]);
}
}
}
//按要求打印前8条记录
for(unsigned int k=0; k<8 && k<filenames.size();k++){
unsigned int blankIdx = filenames[k].rfind(' ');
string file = filenames[k];
if(blankIdx >16)//文件名称超过规定长度。
file = file.erase(0,blankIdx-16);
cout<<file<<" "<<count[k]<<endl;;
}
return 0;
}
``````

string的操作：
s.substr(pos,n); 返回一个string，包含s中从pos开始的n个字符的拷贝。
s.rfind(ch): 找到最后出现ch的位置。
s.find(ch): 找到第一次出现ch的位置。
s.erase(pos,len)

# 华为-简单错误记录

##### 输出描述:

``````交换两个同类型元素，可以直接使用swap函数；

5 7
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 4 5
U 2 9
Q 1 5

5
6
5
9

#include<iostream>
using namespace std;

int main(){
int n,m;
while(cin>>n>>m){
int sorce[n];char op;int A,B;
for(int i=0; i<n; i++)
cin>>sorce[i];
while(m--){
cin>>op>>A>>B;
if( op == 'Q'){
int max = 0;
if(A>B) swap(A,B);
for(int i=A-1; i<B; i++)
max = std::max(max,sorce[i]);
cout<<max<<endl;
}
else if(op == 'U')
sorce[A-1] = B;
}
}

return 0;
}
``````

# 好未来-删除公共字符

``````#include<iostream>
#include<string>
using namespace std;

int main(){
string orgStr;
string delStr;
while(getline(cin,orgStr)){
getline(cin,delStr);
for(int i=0; i<delStr.length();i++){
for (int j=0; j<orgStr.length();j++){
if(orgStr[j] == delStr[i])
orgStr = orgStr.erase(j,1);
}
}
cout<<orgStr<<endl;
}
return 0;
}
``````

# 好未来-字符串组合

``````#include<iostream>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;

void Collect(vector<int>& isIndex, string str, int pos, vector<string>& result) {
if (pos == isIndex.size()) {
result.push_back(str);
return;
}//遍历到最后一个值时，结束递归。
if (isIndex[pos] == 0)//遇0，多一种情况，直接跳过当前值。
Collect(isIndex, str, pos + 1, result);
//不管0/1，这种情况都存在，储存当前值
str += to_string(pos);
Collect(isIndex, str, pos + 1, result);
}

int main() {
vector<int>isIndex;
int a;
while (cin >> a)
isIndex.push_back(a);
vector<string>result;
string str;
Collect(isIndex, str, 0, result);
sort(result.begin(), result.end());
for (int i = 0; i< result.size(); i++)
cout << result[i] << endl;
return 0;
}
``````