2021-11-12每日刷题打卡

2021-11-12每日刷题打卡

AcWing——算法基础

790. 数的三次方根 - AcWing题库

给定一个浮点数 n,求它的三次方根。

输入格式

共一行,包含一个浮点数 n。

输出格式

共一行,包含一个浮点数,表示问题的解。

注意,结果保留 6 位小数。

数据范围

−10000≤n≤10000

输入样例:
1000.00
输出样例:
10.000000

二分查找,这里的数据范围是-10000到10000,那我们就以这个为范围二分查找,每次取中间点,判断中间点的三次方是否等于它给的值,如果相等就退出循环直接输出mid的值。如果不相等,再根据判断大小来决定是取左区间还是右区间。

#include<iostream>
using namespace std;
int main()
{
    double x;
    scanf("%lf",&x);
    double l=-10000,r=10000;
    while(r-l>1e-8)
    {
        double mid=(l+r)/2;
        if(mid*mid*mid>=x)r=mid;
        else l=mid;
    }
    printf("%lf",l);
    return 0;
}
791. 高精度加法 - AcWing题库

给定两个正整数(不含前导 0),计算它们的和。

输入格式

共两行,每行包含一个整数。

输出格式

共一行,包含所求的和。

数据范围

1≤整数长度≤100000

输入样例:
12
23
输出样例:
35

高精度,通俗点来说就是因为数太大了,大到int或long long也无法存下,所以我们采用别的方式来存储这些大的离谱的数。

我们常用的就是把数分成一位一位的然后存入数组里,一开始接收他给的数时,因为正常的整型或浮点型接受不了这么大的数,所以我们把数通过字符串接收,然后通过遍历字符串把各位的字符转成存入vector中(这里的情况,vector比数组要方便,你自己好好想想就知道了),要注意一点是,我们要把字符串逆着存入vector中,比如5201314我们要存成4131025,因为这是为了方便进位,比如我们是990+10,如果是正着存,那vector中的情况也是990,此时结果运算完后是1000,多出来一位,这相当于我们要把原来的数集体后移,这是非常麻烦的,如果我们存的是099,这样只用最后面加1位数就行了。

把要运算的两个数都存在vector后,开始运算,从下标0开始,相同位的加在一起,如果大于10则只取个位数,然后他们的下一位数+1(进位)。最后把结果输出。

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

vector<int> add(vector<int>&A,vector<int>&B)
{
    vector<int>C;
    int t=0;
    for(int i=0;i<A.size()||i<B.size();i++)
    {
        if(i<A.size())t+=A[i];
        if(i<B.size())t+=B[i];
        C.push_back(t%10);
        t/=10;
    }
    if(t)C.push_back(1);
    return C;
}

int main()
{
    string a,b;
    cin>>a>>b;
    vector<int>A,B;
    for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
    
    auto C=add(A,B);
    for(int i=C.size()-1;i>=0;i--)cout<<C[i];
    return 0;
}
792. 高精度减法 - AcWing题库

给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。

输入格式

共两行,每行包含一个整数。

输出格式

共一行,包含所求的差。

数据范围

1≤整数长度≤10^5

输入样例:
32
11
输出样例:
21

总的来说和加法差不多,不同点是减法要考虑结果为负数的可能。我们还是先接收字符串存入vector中,然后要比较两个vector谁大谁小(比长度,要是长度一样就比最高位的数谁大谁小),大的那个做主位去减小的那个,如果顺序和给数时的顺序不同,那输出结果时在开头输出一个负号即可。

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

bool cmp(vector<int>&A,vector<int>&B)
{
    if(A.size()!=B.size())return A.size()>B.size();
    for(int i=A.size()-1;i>=0;i--)
        if(A[i]!=B[i])
            return A[i]>B[i];
    return true;
}

vector<int> sub(vector<int>&A,vector<int>&B)
{
    vector<int>C;
    int t=0;
    for(int i=0;i<A.size();i++)
    {
        t=A[i]-t;
        if(i<B.size())t-=B[i];
        C.push_back((t+10)%10);
        if(t<0)t=1;
        else t=0;
    }
    while(C.size()>1&&!C.back())C.pop_back();
    return C;
}

int main()
{
    string a,b;
    vector<int>A,B;
    cin>>a>>b;
    for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
    if(cmp(A,B))
    {
        auto C=sub(A,B);
        for(int i=C.size()-1;i>=0;i--)cout<<C[i];
    }
    else
    {
        auto C=sub(B,A);
        cout<<"-";
        for(int i=C.size()-1;i>=0;i--)cout<<C[i];
    }
    return 0;
}
235. 二叉搜索树的最近公共祖先剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:

binarysearchtree_improved.png (200×190) (leetcode-cn.com)

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。

while遍历root,每次先判断p和q的值与root的值的关系,如果p和q的val都小于root,说明p和q都在root的左子树,那root就往left方向遍历,如果val都大于root,说明都在右子树,往right遍历,如果一个大一个小,说明一个在左子树一个在右子树,那当前节点就是p和q的最近公共祖先了,返回即可。

/**
 * 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) {
        while(1)
        {
            if(p->val>root->val&&q->val>root->val)
            {
                root=root->right;
            }
            else if(p->val<root->val&&q->val<root->val)
            {
                root=root->left;
            }
            else break;
        }
        return root;
    }
};
700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

例如,

给定二叉搜索树:

    4
   / \
  2   7
 / \
1   3

和值: 2
你应该返回如下子树:

  2     
 / \   
1   3

while遍历root,如果root的val值小于给的val值,说明给的val值应该在root的右子树,root往right方向走;如果大于,说明val应该在左子树,root往left方向走;如果相等,返回root;如果root为NULL,说明到头来也没找到,返回NULL。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        while(1)
            if(!root)break;
            else if(root->val < val)root=root->right;
            else if(root->val > val)root=root->left;
            else if(root->val == val)break;
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值