acwing-18

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

注意:

你的函数应满足下列条件:

  1. 忽略所有行首空格,找到第一个非空格字符,可以是 ‘+/−’ 表示是正数或者负数,紧随其后找到最长的一串连续数字,将其解析成一个整数;
  2. 整数后可能有任意非数字字符,请将其忽略;
  3. 如果整数长度为0,则返回0;
  4. 如果整数大于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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值