目录
1.剑指Offer
面试题:把字符串转换成整数
题目描述:
将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
输入描述:
输入一个字符串,包括数字字母符号,可以为空 输出描述:
如果是合法的数值表达则返回该数字,否则返回0
示例1
输入
+2147483647 1a33 输出
2147483647 0
代码:
class Solution {
public:
int StrToInt(string str) {
int len=str.length();
int s=1;
long long res=0;
if(!len) return 0;
if(str[0]=='-') s=-1;
int i=((str[0]=='+'||str[0]=='-')?1:0);
for(;i<len;i++){
if(!('0'<=str[i]&&str[i]<='9')){
return 0;
}
res=res*10+(str[i]-'0');
}
return res*s;
}
};
面试题66:构建乘积数组
题目描述:
给定一个数组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]。不能使用除法。
思路:解释下代码,设有数组大小为5。
对于第一个
for
循环
第一步:b[0] = 1;
第二步:b[1] = b[0] * a[0] = a[0]
第三步:b[2] = b[1] * a[1] = a[0] * a[1];
第四步:b[3] = b[2] * a[2] = a[0] * a[1] * a[2];
第五步:b[4] = b[3] * a[3] = a[0] * a[1] * a[2] * a[3];
然后对于第二个
for
循环
第一步
temp *= a[4] = a[4];
b[3] = b[3] * temp = a[0] * a[1] * a[2] * a[4];
第二步
temp *= a[3] = a[4] * a[3];
b[2] = b[2] * temp = a[0] * a[1] * a[4] * a[3];
第三步
temp *= a[2] = a[4] * a[3] * a[2];
b[1] = b[1] * temp = a[0] * a[4] * a[3] * a[2];
第四步
temp *= a[1] = a[4] * a[3] * a[2] * a[1];
b[0] = b[0] * temp = a[4] * a[3] * a[2] * a[1];
由此可以看出从b[4]到b[0]均已经得到正确计算。
代码:
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
vector<int> vec;
int len=A.size();
if(len==0) return vec;
vec.push_back(1);
for(int i=0;i<len-1;i++){
vec.push_back(vec.back()*A[i]);
}
int tmp=1;
for(int i=len-1;i>=0;i--){
vec[i]=vec[i]*tmp;
tmp*=A[i];
}
return vec;
}
};
2.Leetcode
例1:不同二叉搜索树的数量
A.题目描述:
思路:递归解法,考虑根节点,设对于任意根节点k,有f(k)种树的可能。比k小的k-1个元素构成k的左子树。则左子树有f(k-1)种情况。比k大的n-k个元素构成k的右子树。则右子树有f(n-k)种情况。易知,左右子树相互独立,所以f(k)=f(k-1)*f(n-k)。综上,对于n,结果为k取1,2,3,...,n时,所有f(k)的和。
代码:
class Solution {
public:
int numTrees(int n) {
if(n<=1) return 1;
int num=0;
for(int i=1;i<=n;i++){
num+=numTrees(i-1)*numTrees(n-i);
}
return num;
}
};
B.
题目描述:
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.
For example,
Given n = 3, your program should return all 5 unique BST's shown below.
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
1 / \ 2 3 / 4 \ 5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
思路:递归实现
代码:
class Solution {
public:
//递归创建
vector<TreeNode *> creatTrees(int left,int right){
vector<TreeNode *> res;
if(left>right){
res.push_back(NULL);
return res;
}
for(int i=left;i<=right;i++){ //以i为根节点的树,其左子树由[1, i-1]构成, 其右子树由[i+1, n]构成。该原则建树具有唯一性
vector<TreeNode *> left_res = creatTrees(left,i-1);
vector<TreeNode *> right_res = creatTrees(i+1,right);
//每个左边的子树跟所有右边的子树匹配,而每个右边的子树也要跟所有的左边子树匹配,总共有左右子树数量的乘积种情况
int lsize = left_res.size();
int rsize = right_res.size();
for(int j=0;j<lsize;j++){
for(int k=0;k<rsize;k++){
TreeNode *root = new TreeNode(i);
root->left = left_res[j];
root->right = right_res[k];
res.push_back(root);
}
}
}
return res;
}
vector<TreeNode *> generateTrees(int n) {
//本题主要考察二叉排序树的构建
//unique-binary-search-trees-i,我们可以知道结果的数目是一个卡特兰数列,当本题需要把所有可能的二叉排序
//给构建出来要求解所有的树,自然是不能多项式时间内完成的思路是每次一次选取一个结点为根,然后递归求解左右子树的所有结果,最后根据左右子树的返回的所有子树,依次选取
//然后接上(每个左边的子树跟所有右边的子树匹配,而每个右边的子树也要跟所有的左边子树匹配,总共有左右子树数量的乘积种情况),构造好之后作为当前树的
//结果返回
return creatTrees(1,n); //从1作为root开始,到n作为root结束
}
};
例2:转化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".
思路:
0 4 8
1 3 5 7 9
2 6 10
可以发现 当行数为3的时候 每4个数组成一个周期
行数为nRows的时候 周期t= 2*nRows-2
[0,nRows-1) 向下 [nRows,t) 向上
初始化一个 nRows 行的vector 依次将string中的每一个放入,在合并。
代码:
class Solution {
public:
string convert(string s, int nRows) {
if(nRows<=1) return s;
string res="";
vector<string> m(nRows,res);
int t=nRows+nRows-2; //周期
for(int i=0;i<s.length();i++){
int a=i%t;
if(a<nRows){ //往下走
m[a]+=s[i];
}
else{ //往上走
m[t-a]+=s[i];
}
}
for(int i=0;i<nRows;i++){ //合并
res+=m[i];
}
return res;
}
};