Leetcode Top 100 Liked Questions(序号105~139)

news2024/11/28 11:52:11

105. Construct Binary Tree from Preorder and Inorder Traversal105. Construct Binary Tree from Preorder and Inorder Traversal

题意:根据前序遍历和中序遍历来构造二叉树

我的思路

要用递归造树,要同时递归左子树和右子树,造树需要左边边界和右边边界

build函数有树的跟指针,前序的有左边边界和右边边界,中序的左边边界和右边边界

如果l>r return;因为是先序遍历,所以左子树是先序的第一个,先构造了;

不会做不会做

标答

上面标粗的部分是正确的,构造就在递归的时候构造,不用把树的根作为指针放到参数里面

之后就是搞清楚pl,pr和ir,il就可以了【做着做着居然做出来了!!】

例子:前序[3,0,9,4,62,5,7,8,1]

中序[4,9,6,0,2,3,5,8,7,1]

显而易见,左子树的pl是pl+1;左子树的il是il;左子树的ir是pos-1;

显而易见,右子树的pr=pr;右子树的il是pos+1;右子树的ir是ir

左子树是[ il,pos-1]的长度,所以pr=pl+1+pos-1-li=pl+pos-li;

右子树是[pos+1,ir]的长度,所以pl=左子树的pr+1=pl+pos-li+1

                                                       =pr-(ir-pos-1)=pr-ir+pos+1

代码 Runtime 30 ms Beats 34.48% Memory 25.9 MB Beats 73.83%

class Solution {
public:
    TreeNode*build(vector<int>& preorder, vector<int>& inorder,int pl,int pr,int il,int ir){
        if(il>ir)return NULL;
        TreeNode *root=new TreeNode(preorder[pl]);
        int pos;//为了找到il和ir
        for(int i=il;i<=ir;i++)
            if(inorder[i]==preorder[pl]){pos=i;break;}
        root->left=build(preorder,inorder,pl+1,pl+pos-il,il,pos-1);
        root->right=build(preorder,inorder,pr-ir+pos+1,pr,pos+1,ir);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n=preorder.size()-1;
        TreeNode *root=NULL;
        return build(preorder,inorder,0,n,0,n);
    }
};

标答优化 map

题目中有这样一条preorder and inorder consist of unique values.

所以可以用map来减少中序查找的时间消耗

传递参数的时候可以省略前序序号的传递,或者说只需要一个pl就可以了,传递的时候函数参数为il和ir

代码 Runtime13 ms Beats 79.95% Memory26.3 MB Beats 58.43%

class Solution {
public:
    unordered_map<int,int>mp;
    int pre=0;
    TreeNode* build(vector<int>& preorder,int l,int r){
        if (l>r) return NULL;
        int mid=preorder[pre++];
        TreeNode * root=new TreeNode(mid);
        int pos=mp[mid];
        root->left=build(preorder,l,pos-1);
        root->right=build(preorder,pos+1,r);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n=inorder.size()-1;
        for(int i=0;i<=n;i++) mp[inorder[i]]=i;//中序序列的这个数字排在第几个序号
        return build(preorder,0,n);
    }
};

114. Flatten Binary Tree to Linked List

题意:

我的思路 

先序索引,但我不会写;看了答案后至少有一点是对的,就是先递归,两个递归后在做事情

标答 递归

分为4种情况:1只有左边的,2只有右边的,3都没有的,4都有的

首先是第一种情况,假设现在root是1这个结点【56当它不存在】,234按照道理都已经建好了;只需要root->right=root->left; root->left=NULL;就可以了

第二种情况,假设节点是5,6按道理都建好了,其实5放着不动就好了

第三种情况就先不管

第四种情况,假设节点是2,34按道理都建好了,首先要把右子树空出来,right=root->right; root->right=root->left;root->left=NULL;  这时候还需要处理原来在右子树上的结点。因为原先左子树上的都是处理好的链表,所以只要找到原先左子树上的最后一个节点,把这最后一个节点连上去就可以了

代码 递归 Runtime 5 ms Beats 59.24% Memory 12.7 MB Beats 30.44%

class Solution {
public:
    void flatten(TreeNode* root) {
        if(root==NULL)return;
        flatten(root->left);
        flatten(root->right);
        if(root->left){
            TreeNode* right=root->right;
            root->right=root->left;
            root->left=NULL;
            while(root->right)root=root->right;
            root->right=right;
        }
    }
};

标答 循环

首先如果root是空的话就返回;如果当前指针有左指针,先将pre指向左指针指向的位置;pre来到左指正的最右边,左指针的最右边指向当前指针的右边,再把原来右指针指向左指针的位置,左指针置为空;如下图所示,总之就是一点一点挪过去 

代码 Runtime 3 ms Beats 88.18% Memory12.7 MB Beats 61.31%

class Solution {
public:
    void flatten(TreeNode* root) {
        if(root == NULL) return;
        TreeNode *curr = root;
        while(curr){
            if(curr->left){
                TreeNode *pre = curr->left;
                while(pre->right) pre = pre->right;
                pre->right = curr->right;
                curr->right = curr->left;
                curr->left = NULL;
            }
            curr = curr->right;
        }
    }
};

标答 优化

注意这里是先递归右边,相当于(我一开始想的)先到右边的尽头,之后那前一个来接上的想法【最后没写出来】

注意这里递归的顺序,学着点!!

先递归到6,这时6的右指针是prev也就是空,左指针是空,prev是6

接下来是5,5的右指针是prev也就是6,左指针是空,prev是5

接下来是4,4的右指针是prev也就是5,左指针是空,prev是4

接下来是3,3的右指针是prev也就是4,左指针是空,prev是3

……

于是就完成了

代码 Runtime 0 ms Beats 100% Memory12.7 MB Beats 30.44%

class Solution {
public:
TreeNode* prev = NULL; 
    void flatten(TreeNode* root) {
        if(!root) return;
        flatten(root->right);
        flatten(root->left);
        root->right = prev;
        root->left = NULL;
        prev = root;
    }
};

118. Pascal's Triangle

题意:

 我的思路

用动态规划(?),第x层有x个数字,dp[x][0]=1,dp[x][x-1]=0,dp[x][i]=dp[x-1][i-1]+dp[x-1][i]

 代码 Runtime 4 ms Beats 29.4% Memory 6.9 MB Beats 18.4%

class Solution {
public:
    vector<vector<int>> generate(int num) {
        if(num==1)return {{1}};
        if(num==2)return {{1},{1,1}};
        vector<vector<int>> ans={{1},{1,1}};int temp=0;
        for(int x=3;x<=num;x++){//一共num层
            vector<int> sol;sol.push_back(1);
            for(int i=1;i<x-1;i++){
                temp=ans[x-2][i-1]+ans[x-2][i];
                sol.push_back(temp);
            }
            sol.push_back(1);
            ans.push_back(sol);
        }
        return ans;
    }
};

标答 优化

简而言之,就是用一维数组代替了二维数组,实现了相加提速

代码 Runtime 0 ms Beats 100% Memory 6.7 MB Beats 78.55%

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>>ans;
        ans.push_back({1});
        for(int i=0;i<numRows-1;i++){
         vector<int> tem=ans.back();//{1}
         vector<int> v(tem.size()+1);//开空间
         for(int i=0;i<=tem.size();i++){
            if(i==0){
                v[i]=tem[0];continue;//1
            }
            if(i==tem.size())//1
                v[i]=tem[tem.size()-1];
            else
                v[i]=tem[i-1]+tem[i];
         }
         ans.push_back(v);
        }
        return ans;
    }
};

121. Best Time to Buy and Sell Stock

题意:给出每天袜子的价格,只能选一天买袜子,只能选一天卖袜子,求利润最大

我的思路

用vector或者deque模拟单调栈?当要弹出一个大的数字的时候,就求一下栈尾和栈顶的的差,或者双指针也可以

代码 双指针 Runtime 66 ms Beats 99.76% Memory 93.4 MB Beats 11.73%

不加取消同步在66.7%左右,感觉都差不多,都是找个最小的,然后当前的减去现在最小的,最后在"当前的"里面找最大的

class Solution {
public:
    int maxProfit(vector<int>& p) {
        int l=0,r=0,n=p.size();int profit=0;
        for(r=1;r<n;r++){
            profit=max(profit,p[r-1]-p[l]);
            if(p[r]<p[l])l=r;
        }
        profit=max(profit,p[r-1]-p[l]);
        return profit;
    }
};

124. Binary Tree Maximum Path Sum

题意:树上路径和最大

我的思路

学过,好像有两种做法?一种dp一种dfs大概?

下面是用dfs做的:

那就每个结点都遍历一遍,每个节点的数字就是 sum=左边的和加上右边的和,ans=max(ans, sum);返回的时候返回两条子树和最大的那个,如果和是负的那就返回0

代码 Runtime 17 ms Beats 85.76% Memory27.7 MB Beats 52.24%

class Solution {
public:
    int ans=-9999;
    int maxP(TreeNode* root) {
        int l=0;int r=0;int sum=0;
        if(root->left!=NULL) l=maxP(root->left);
        if(root->right!=NULL) r=maxP(root->right);
        sum=l+r+(root->val);
        ans=max(ans,sum);
        return max(max(l,r)+(root->val),0);
    }
    int maxPathSum(TreeNode* root) {
        maxP(root);
        return ans;
    }
};

128. Longest Consecutive Sequence

题意:输出最长连续序列的长度

我的思路

初步设想快排+遍历,但是他会有相同的数字;那就用map

代码 Runtime 147 ms Beats 60.73% Memory 68.8 MB Beats 26.14%

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        ios::sync_with_stdio(false);cin.tie(0);
        if(nums.size()==0)return 0;
        map<long long,int>mp;int maxx=1;
        long long pre=-9999999999;int cnt=0;
        for(int i=0;i<nums.size();i++)
            mp[nums[i]]++;
        for(auto q:mp){
            if(cnt!=0&&q.first!=pre+1){
                maxx=max(maxx,cnt); cnt=0;
            }
            pre=q.first;
            cnt++;
        }
        maxx=max(maxx,cnt);
        return maxx;
    }
};

标答 排序

我的2n比不上nlogn,好吧;其实和初步设想差不多,就是相同的数字的时候不加就可以了

首先先排序,之后

代码 Runtime 35 ms Beats 99.79% Memory43.2 MB Beats 99.65%

class Solution {
public:
    int longestConsecutive(vector<int>& nums){
        ios_base::sync_with_stdio(false);cin.tie(NULL);
        int n=nums.size();
        if(n==0)return 0;
        int maxx=0;int cnt=1;
        sort(nums.begin(),nums.end());
        for(int i=1;i<n;i++){
            if(nums[i]-nums[i-1]==1)cnt++;
            else if(nums[i]!=nums[i-1]){
                maxx=max(maxx,cnt);cnt=1;
            }
        }
        maxx=max(maxx,cnt);
        return maxx;
    }
};

131. Palindrome Partitioning

题意:给一个字符串,返回所有是回文串的子串

我的思路

初步设想O(n^2)的遍历+回文串判断,但是这个返回的答案很dfs

那就试试用dfs做吧;不会做不会做

但是瞄了一眼标答 还是自己写了

代码 Runtime 75 ms Beats 94.39% Memory 49.3 MB Beats 82.17%

class Solution {
public:
    bool jud(string s){
        int n=s.size();
        for(int i=0;i<n/2;i++){
            if(s[i]!=s[n-i-1])return 0;
        }
        return 1;
    }
    void dfs(vector<vector<string>> &result,vector<string> &sol,int id,string &s){
        if(id==s.size()){
            result.push_back(sol);return;
        }
        for(int len=1;len+id<=s.size();len++){
            string temp=s.substr(id,len);
            if(jud(temp)){
                sol.push_back(temp);
                dfs(result,sol,id+len,s);
                sol.pop_back();
            }
        }
    }
    vector<vector<string>> partition(string s) {
        if(s.size()==0)return {{}};
        vector<vector<string>> result;
        vector<string> sol;
        dfs(result,sol,0,s);
        return result;
    }
};

136. Single Number

题意:给一个数组,找出只出现一次的数字

我的思路

用map存一遍,在找一遍

代码 Runtime17 ms Beats 59.59% Memory20.1 MB Beats 9.40%

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        ios::sync_with_stdio(false);cin.tie(0);
        unordered_map<int,int>mp;
        for(int i=0;i<nums.size();i++)
            mp[nums[i]]++;
        for(auto q:mp)
            if(q.second==1)return q.first;
        return 0;
    }
};

标答 位运算 

首先是异或算法的一些规律

从上图就可以看到,如果是两个一样的数字,那么它就会变成0;如果是不一样的数字,那么它就会留下来

代码 Runtime11 ms Beats 92.56% Memory 17 MB Beats 33.22%

class Solution {
public:
    int singleNumber(vector<int>& nums) {
      int x = 0;
      for(int i=0; i<nums.size(); i++)
          x=x^nums[i];
      return x;
    }
};

138. Copy List with Random Pointer

题意:复制一个一摸一样的链表

我的思路

只会链表的顺序复制,如果是随机的,那要有个map,左边是原地址,右边是现地址;

代码 Runtime 3 ms Beats 97.9% Memory11.3 MB Beats 32.3%

class Solution {
public:
    Node* copyRandomList(Node* head) {
        unordered_map<Node*,Node*>mp;
        if(head==NULL)return NULL;
        Node* root=new Node(head->val);
        Node* q=root;Node* cr=NULL;mp[head]=root;
        for(Node* p=head->next;p!=NULL;p=p->next){
            cr=new Node(p->val);
            q->next=cr;q=q->next;
            mp[p]=cr;
        }
        q=root;
        for(Node* p=head;p!=NULL;p=p->next){
            Node* qv=p->random;
            q->random=mp[qv];
            q=q->next;
        }
        return root;
    }
};

标答 不用map的做法

如果head是空,返回空;

copy_merge函数复制顺序的链表,其中curr是原链表的当前节点,next是原链表的下一个节点,copy是专门创造新结点的指针,curr指向新生的结点,copy指向原来下一个节点;其返回结果如图所示

handle_random函数如下如所示,简单来说就是复制的结点就是原节点的next,所以容易能找到;这样就可以原来的节点的random指向哪个复制的节点就指向那个节点的next

最后detach函数把复制的结点全部都串在一起,原来的结点也要指回原来的结点

代码 Runtime 7 ms Beats 73.26% Memory 11.2 MB Beats 87.73%

class Solution {
public:
    void copy_merge(Node* head){
        Node* curr=head; Node* next=head->next;
        while(curr!=NULL){
            Node* copy=new Node(curr->val);
            curr->next=copy; copy->next=next;
            curr=next;
            if(next!=NULL) next=next->next;
        }
    }
    void handle_random(Node* head){
        Node* curr=head;
        while(curr!=NULL){
            if(curr->random!=NULL) curr->next->random=curr->random->next;
            curr=curr->next->next;
        }
    }
    Node* detach(Node* head){
        Node* curr=head; Node* dummy=new Node(-1); Node* tail=dummy;
        while(curr!=NULL){
            tail->next=curr->next; tail=tail->next;
            curr->next=tail->next; curr=curr->next;
        }
        return dummy->next;
    }
    Node* copyRandomList(Node* head) {
        if(head==NULL) return head;
        copy_merge(head); handle_random(head);
        return detach(head);
    }
};

139. Word Break

题意:给你字典,问能不能用字典里的词拼接成字符串s

我的思路

用dfs吗?但是dfs先分成所有可能性,再用字典判断也太费时间了吧

不会做,看看答案

标答 动态规划

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/952160.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ansible学习笔记9

yum_repository模块&#xff1a; yum_repository模块用于配置yum仓库的。 测试下&#xff1a; [rootlocalhost ~]# ansible group1 -m yum_repository -a "namelocal descriptionlocalyum baseurlfile:///mnt/ enabledyes gpgcheckno" 192.168.17.106 | CHANGED &g…

【微服务部署】08-监控与告警

文章目录 1. PrometheusOperator1.1 优势1.2 配置脚本1.3 部署脚本 2. Granfana实现监控看板2.1 Granfana核心特性2.2 部署文件 目前Kubernetes中最流行的监控解决方案是使用Prometheus和AlertManager 1. PrometheusOperator 1.1 优势 自动化安装将配置资源化灵活的扩展能力 …

2023开学季《乡村振兴战略下传统村落文化旅游设计》许少辉博士八一新书已被北京收录

2023开学季《乡村振兴战略下传统村落文化旅游设计》许少辉博士八一新书已被北京收录

【AI】数学基础——数理统计(假设检验数据处理)

概率论 数理统计&#xff08;概念&参数估计&#xff09; 文章目录 3.8 假设检验3.8.1 提出假设3.8.2 构建检验统计量对均值检验对方差检验 3.8.3 根据显著性水平确定拒绝域临界值显著性水平拒绝域 3.8.4 计算统计量&#xff0c;确定P值3.8.5 根据临界值法决定是否拒绝原假设…

PCD点云文件外部框框坐标计算

PCD点云文件直接提取的是点云的坐标&#xff0c;不是最外面的box的坐标&#xff0c;因此可以通过&#xff1a; max_b octree.get_max_bound() min_b octree.get_min_bound()分别得到最大最小的xyz坐标&#xff0c;之后进行计算 点的序号和位置对应如下&#xff1a; 所有的…

UML用例图三种关系(重点)-架构真题(十七)

某项目包括A、B、C、D四道工序&#xff0c;各道工序之间的衔接关系、正常进度下各工序所需的时间和直接费用、赶工进度下所需的时间和直接费用如下表所示。该项目每天需要间接费用为4.5万元&#xff0c;根据此表&#xff0c;最低成本完成需要&#xff08;&#xff09;天。&…

selenium可以编写自动化测试脚本吗?

Selenium可以用于编写自动化测试脚本&#xff0c;它提供了许多工具和API&#xff0c;可以与浏览器交互&#xff0c;模拟用户操作&#xff0c;检查网页的各个方面。下面是一些步骤&#xff0c;可以帮助你编写Selenium自动化测试脚本。 1、安装Selenium库和浏览器驱动程序 首先…

【QT】使用qml的QtWebEngine遇到的一些问题总结

在使用qt官方的一些QML的QtWebEngine相关的例程的时候&#xff0c;有时在运行会报如下错误&#xff1a; WebEngineContext used before QtWebEngine::initialize() or OpenGL context creation failed 这个问题在main函数里面最前面加上&#xff1a; QCoreApplication::setAttr…

深度学习推荐系统(二)Deep Crossing及其在Criteo数据集上的应用

深度学习推荐系统(二)Deep Crossing及其在Criteo数据集上的应用 在2016年&#xff0c; 随着微软的Deep Crossing&#xff0c; 谷歌的Wide&Deep以及FNN、PNN等一大批优秀的深度学习模型被提出&#xff0c; 推荐系统全面进入了深度学习时代&#xff0c; 时至今日&#xff0c…

【数据分享】2000-2020年全球人类足迹数据(无需转发\免费获取)

人类足迹(Human Footprint)是生态过程和自然景观变化对生态环境造成的压力&#xff0c;是世界各国对生物多样性和生态保护的关注重点。那如何才能获取长时间跨度的人类足迹时空数据呢&#xff1f; 之前我们分享了来自于中国农业大学土地科学与技术学院的城市环境监测及建模&am…

实时语义分割网络 BiSeNet , RK1126 Npu 推理

记录下在rk1126上&#xff0c;实现 BiSeNet 网络推理. https://github.com/CoinCheung/BiSeNet ONNX 生成 onnx 模型 python tools/export_onnx.py --config configs/bisenetv2_city.py --weight-path ./checkpoints/model_final_v2_city.pth --outpath ./checkpoints/mode…

每日一题(反转链表)

每日一题&#xff08;反转链表&#xff09; 206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 可以定义一个新的newhead结构体指针。再定义cur指针和next指针互相配合&#xff0c;将原链表中的节点从头到尾依次头插到newhead链表中&#xff0c;同时更…

使用爬虫代码获得深度学习目标检测或者语义分割中的图片。

问题描述&#xff1a;目标检测或者图像分割需要大量的数据&#xff0c;如果手动从网上找的话会比较慢&#xff0c;这时候&#xff0c;我们可以从网上爬虫下来&#xff0c;然后自己筛选即可。 代码如下&#xff08;不要忘记安装代码依赖的库&#xff09;&#xff1a; # -*- co…

记一次特殊的HTTP 500.30

此错误比较常见&#xff0c;网上的解决方式各种各样&#xff0c;今天遇到的情况是&#xff0c;除过配置文件别的程序集都一样&#xff0c;程序部署端口不同&#xff0c;最后检查原因竟然是appsettings配置文件 key值的格式问题&#xff08;中英文字符或者空格导致&#xff0c;粘…

【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之键控流水灯(三)

本原创教程由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处 适用于板卡型号&#xff1a; 紫光同创PGL22G开发平台&#xff08;盘古22K&#xff09; 一&#xff1a;盘古22K开发板&#xff08;紫光同创PGL22G开发…

Java8实战-总结17

Java8实战-总结17 引入流流操作中间操作终端操作使用流 小结 引入流 流操作 java.util.stream.Stream中的Stream接口定义了许多操作。它们可以分为两大类。再来看一下前面的例子&#xff1a; List<String> names menu.stream() //从菜单获得流 .filter(d -> d.get…

基于Java的OA办公管理系统,Spring Boot框架,vue技术,mysql数据库,前台+后台,完美运行,有一万一千字论文。

基于Java的OA办公管理系统&#xff0c;Spring Boot框架&#xff0c;vue技术&#xff0c;mysql数据库&#xff0c;前台后台&#xff0c;完美运行&#xff0c;有一万一千字论文。 系统中的功能模块主要是实现管理员和员工的管理&#xff1b; 管理员&#xff1a;个人中心、普通员工…

etcd读写请求的执行过程

etcd读请求如何执行 首先&#xff0c;etcdctl 会对命令中的参数进行解析。在解析完请求中的参数后&#xff0c;etcdctl 会创建一个 clientv3 库对象通过gRPC API来访问 etcd server。对应流程一。 然后通过负载均衡算法选择一个etcd server节点&#xff0c;然后调用 etcd ser…

Redis之管道解读

目录 基本介绍 使用例子 管道对比 管道与原生批量命令对比 管道与事务对比 使用pipeline注意事项 基准测试 基本介绍 Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务器。 这意味着请求通常按如下步骤处理&#xff1a; 客户端发送一个请求到服务器&am…

飞天使-python的模块与包与装饰器

文章目录 模块与包标准模块第三方模块自定义模块 高级语法切片迭代器/生成器高级模式&#xff08;闭包&#xff09;高级模式&#xff08;装饰器&#xff09; 参考视频 模块与包 标准模块 import os print(os.getcwd())import sys print(sys.argv) print(sys.platform) print(…