acwing-18
构建乘积数组(中等)
给定一个数组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]
。
不能使用除法。
样例
输入:[1, 2, 3, 4, 5]
输出:[120, 60, 40, 30, 24]
思考题:
- 能不能只使用常数空间?(除了输出的数组之外)
题解
- 将结果分为两个部分一个是0 — i-1 一部分是i+1 — n-1
- 所以这里设置两个数组,一个数组是记录左部分
left[i
] 0 — i-1的内容,另一部分右边部分right[i]
记录了 i+1 — n-1的内容 - 那么
B[i]=left[i]*right[i]
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
vector<int> left(A.size(),1);
vector<int> right(A.size(),1);
for(int i=1;i<A.size();i++)
left[i]*=A[i-1]*left[i-1];
for(int i=A.size()-2;i>=0;i--)
right[i]*=A[i+1]*right[i+1];
vector<int> res;
for(int i=0;i<A.size();i++)
res.push_back(left[i]*right[i]);
return res;
}
};
- 若是采用常量空间,那么便是采用一个变量动态的记录0 — i-1 部分
- 在记录了 i+1 — n-1的内容,一遍计算一遍算出结果
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
if(A.size()==0)return vector<int>{};
int p=A[0];
vector<int> res(A.size(),1);
for(int i=1;i<A.size();i++){
res[i]=p;p*=A[i];
}
p=A.back();
for(int i=A.size()-2;i>=0;i--){
res[i]*=p;p*=A[i];
}
return res;
}
};
把字符串转换成整数(中等)
请你写一个函数StrToInt,实现把字符串转换成整数这个功能。
当然,不能使用atoi或者其他类似的库函数。
样例
输入:"123"
输出:123
注意:
你的函数应满足下列条件:
- 忽略所有行首空格,找到第一个非空格字符,可以是 ‘+/−’ 表示是正数或者负数,紧随其后找到最长的一串连续数字,将其解析成一个整数;
- 整数后可能有任意非数字字符,请将其忽略;
- 如果整数长度为0,则返回0;
- 如果整数大于INT_MAX(2^31 − 1),请返回INT_MAX;如果整数小于INT_MIN(−2^31) ,请返回INT_MIN;
题解
- 按照提示一步步来即可
- 剔除首行空格
- 判断数字正负
- 每次判断注意边界条件
- 整合字符数字
- 判断正负数是否超过int的边界,所以采用long long int
class Solution {
public:
int strToInt(string str) {
int k=0;
long long int res=0;
bool is_fu=false;
while(k<str.size()&&str[k]==' ')k++;
if(k<str.size()&&str[k]=='-'){is_fu=true;k++;}
else if(k<str.size()&&str[k]=='+'){is_fu=false;k++;}
while(k<str.size()&&str[k]>='0'&&str[k]<='9'){res=res*10+(str[k]-'0');k++;}
if(is_fu){
res=-res;
if(res<INT_MIN)return INT_MIN;
return res;
}else{
if(res>INT_MAX)return INT_MAX;
return res;
}
}
};
树中两个结点的最低公共祖先(中等)
给出一个二叉树,输入两个树节点,求它们的最低公共祖先。
一个树节点的祖先节点包括它本身。
注意:
- 输入的二叉树不为空;
- 输入的两个节点一定不为空,且是二叉树中的节点;
样例
二叉树[8, 12, 2, null, null, 6, 4, null, null, null, null]如下图所示:
8
/ \
12 2
/ \
6 4
1. 如果输入的树节点为2和12,则输出的最低公共祖先为树节点8。
2. 如果输入的树节点为2和6,则输出的最低公共祖先为树节点2。
题解
- 递归查找两个节点出现的位置
- 如果两个节点分别在左子树,和右子树出现,那么公共节点是根节点
- 如果全部在左子树,那么就是公共节点在左子树中,反之就是在右子树
/**
* 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:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL)return NULL;
if(root==q||root==p)
return root;
TreeNode *l=lowestCommonAncestor(root->left,p,q);
TreeNode *r=lowestCommonAncestor(root->right,p,q);
if(l!=NULL&&r!=NULL)
return root;
if(l==NULL)
return r;
else
return l;
}
};