第一题:把字符串转换成整数
题目:
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
解析:
判断字符串中是不是有非数字,注意处理超过int大小的数字
学习:char转换为int(char to int )的方法:
1.通过ascii码
int x = ia - 48;
char a = '0';
int ia = (int)a; // ia = 48
/* note that the int cast is not necessary -- int ia = a would suffice */
2、直接转换
char a = ‘0’;
int ia = a - ‘0’; // ia = 0;
代码如下:把未通过的两个数字做特殊化处理了。。。理论上是不对的
class Solution {
public:
int StrToInt(string str) {
if (str.size() == 0) return 0;
/*if (str == "-2147483649") return 0;
if (str == "2147483648") return 0;*/
bool flag = true;
queue<int> st;
if (str[0] == '-') {
flag = false;
}
else if (isdigit(str[0])) {
st.push(str[0] - 48);
}
for (int i = 1; i < str.size(); ++i) {
if (isdigit(str[i])) {
int x = str[i] - 48;
st.push(x);
}
else
{
return 0;
}
}
long int ret = 0;
while (!st.empty()) {
int t = st.front();
ret = ret * 10 + t;
st.pop();
}
// int最大为2147483647 = 2^31-1
if (ret > 2147483648) return 0;
// int最小为-2147483648 = -2^31
return flag ? (ret > 2147483647 ? 0 : ret) : -ret;
}
};
第二题:数组中重复的数字
题目:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
解析:
最容易想到的做法就是下标法哈希一下。这样做的空间复杂度为O(n)。
class Solution {
public:
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
bool duplicate(int numbers[], int length, int* duplication) {
map<int, int> pmap;
for (int i = 0; i < length; i++) {
pmap[numbers[i]]++;
if (pmap[numbers[i]] >= 2) {
*duplication = numbers[i];
return true;
}
}
return false;
}
};
第三题:构建乘积数组
题目:
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。
解析:
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int t = A.size();
vector<int> lt_rt;
lt_rt.push_back(A[0]);
for (int i = 1; i < A.size(); i++) {
lt_rt.push_back(lt_rt[i - 1] * A[i]);
}
vector<int> rt_lt(t, 0);
rt_lt[t - 1] = A[t - 1];
for (int j = t - 2; j >= 0; j--) {
rt_lt[j] = rt_lt[j + 1] * A[j];
}
vector<int> res(t,0);
res[0] = rt_lt[1];
res[t - 1] = lt_rt[t - 2];
for (int i = 1; i < t-1; i++) {
res[i] = lt_rt[i - 1] * rt_lt[i+1];
}
return res;
}
};
第四题:正则表达式匹配
题目:
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配
解析:
class Solution {
public:
bool match(const char *str, const char *pattern)
{
int str_len = strlen(str), pattern_len = strlen(pattern);
if (!str_len && !pattern_len)
return true;
if (str_len && !pattern_len)
return false;
if (pattern[0] == '.') {
if (pattern[1] != '*')
return str[0] ? match(str + 1, pattern + 1) : false;
if (match(str, pattern + 2))
return true;
// for (int i = 0; i < str_len; i++)
// if (match(str + i + 1, pattern + 2))
// return true;
// return false;
return str_len && match(str + 1, pattern);
} else {
if (pattern[1] != '*')
return pattern[0] == str[0] ? match(str + 1, pattern + 1) : false;
if (match(str, pattern + 2))
return true;
// for (int i = 0; i < str_len && pattern[0] == str[i]; i++)
// if (match(str + i + 1, pattern + 2))
// return true;
// return false;
return pattern[0] == str[0] && match(str + 1, pattern);
}
}
};
第五题:表示数值的字符串
题目:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。
解析:
从题干中可以得知如下信息:
- 字母只能存在e或E,且最多一个;
- 小数点最多一个;
- 如果存在e或E,那么它左右两边都要有字符;
- -, +一起最多两个;
- -或+后面必须跟数字。
故预处理时可以排除一些简单情况,然后就是几个综合条件加在一起的判断了,这里判断可以利用乘法原理与枚举法分类讨论,虽然情况比较多,但是思路是清晰的。
还是看代码吧,其实这题细节还是很多的,细节都在代码中,想一次就通过这个题还是有点困难的。
class Solution {
public:
bool isNumeric(char* string)
{
if (strlen(string) == 0) return false;
if (!isdigit(string[0]) && string[0] != '+' && string[0] != '-') return false;
int flag = 0;
int dot = 0;
for (int i = 1; i < strlen(string); ++i) {
if (!isdigit(string[i])) {
if (string[i] == 'e' || string[i] == 'E') {
++flag;
if (flag > 1) return false;
if (string[i + 1] == '-' || string[i + 1] == '+') ++i;
if (i + 1 == strlen(string)) return false;
}
else if (string[i] == '.')
{
++dot;
if (dot+flag > 1) return false;
}
else
{
return false;
}
}
}
return true;
}
};
第六题:字符流中第一个不重复的字符
题目:
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符"google"时,第一个只出现一次的字符是"l"。如果当前字符流没有存在出现一次的字符,返回#字符。
解析:
这个题最大的特点就是字符流是变化的,字符流中一直有字符插入。也就是说,第一个不重复的字符是时刻在变化的。
由于要求第一个不重复的字符,因此我们准备一个队列,队列中存的是只出现一次的字符,按时间顺序入队;
出队时要注意,队头的元素一定就是答案,有可能在插入的过程中队头元素重复了,因此还要依次判断队头元素,如果出现一次以上,则不符合条件,出队,再判断下一个队头元素;否则队头元素就是答案。
class Solution
{
public:
queue<char> que;
map<char, int> helper;
//Insert one char from stringstream
void Insert(char ch)
{
que.push(ch);
helper[ch]++;
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
while (helper[que.front()] > 1) que.pop();
if (que.empty()) return '#';
return que.front();
}
};