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

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和irfor(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())//1v[i]=tem[tem.size()-1];elsev[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.rhkb.cn/news/112061.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言每日一练-----Day(4)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;记负均正    旋转数组的最小数字    二分查找 &#x1f493;博主…

剑指offer(C++)-JZ29:顺时针打印矩阵(算法-模拟)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 题目描述&#xff1a; 输入一个矩阵&#xff0c;按照从外向里以顺时针的顺序依次打印出每一个数字&#xff0c;例如&#xff0c;…

element Collapse 折叠面板 绑定事件

1. 点击面板触发事件 change <el-collapse accordion v-model"activeNames" change"handleChange"><el-collapse-item title"一致性 Consistency"><div>与现实生活一致&#xff1a;与现实生活的流程、逻辑保持一致&#xff0c…

使用Python构建网络爬虫:提取网页内容和图片资源

网络爬虫是一种自动获取网页内容的程序&#xff0c;它可以帮助我们高效地收集网络上的有价值信息。本文将介绍如何使用Python构建网络爬虫&#xff0c;提取网页内容和图片资源。   一、环境准备   1.安装Python环境   首先&#xff0c;确保您已经安装了Python环境。访问P…

2021年06月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;数字变换 给定一个包含5个数字&#xff08;0-9&#xff09;的字符串&#xff0c;例如 “02943”&#xff0c;请将“12345”变换到它。 你可以采取3种操作进行变换 &#xff08;1&#xff09;交换相邻的两个数字 &#xff08;2&#xff09;将一个数字加1。如果…

Qt应用开发(基础篇)——进度条 QProgressBar

一、前言 QProgressBar类继承于QWidget&#xff0c;是一个提供了横向或者纵向进度条的小部件。 QProgressBar进度条一般用来显示用户某操作的进度&#xff0c;比如烧录、导入、导出、下发、上传、加载等这些需要耗时和分包的概念&#xff0c;让用户知道程序还在正常的执行中。 …

Git操作

Git 操作方法 Git 是一个分布式版本控制系统&#xff0c;用于管理项目的源代码。 gitee新建仓库提示如下 具体介绍看下面 1. 创建仓库 初始化本地仓库 使用以下命令在本地目录中初始化一个新的 Git 仓库&#xff1a; git init克隆远程仓库 使用以下命令克隆一个远程仓库…

java自动登录 selenium 自动登录并获取cookie

选择操作网页 我用的edge&#xff0c;谷歌我的版本太高没有对应的驱动… 下载Edge的驱动程序&#xff0c;直接解压就好里面只有一个.exe文件 https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ 复制即用&#xff0c;看注释 import com.alibaba.fastjs…

我们的第一个 Qt 窗口程序

Qt 入门实战教程&#xff08;目录&#xff09; Windows Qt 5.12.10下载与安装 为何使用Qt Creator开发QT 本文介绍用Qt自带的集成开发工具Qt Creator创建Qt默认的窗口程序。 本文不需要你另外安装Visual Studio 2022这样的集成开发环境&#xff0c;也不需要你再在Visual St…

Redis.conf 配置文件详解

1、units 单位 配置大小单位&#xff0c;开头定义了一些基本的度量单位&#xff0c;只支持 bytes&#xff0c;不支持bit&#xff0c;并且对大小写 不敏感。 2、INCLUDES 包含 类似于 Spring 配置文件&#xff0c;可以通过 includes 包含&#xff0c;redis.conf 可以作为总文件…

JVM运行时数据区

文章目录 JVM内存结构图1、运行时数据区域JDK 1.7JDK 1.81. 线程栈&#xff08;虚拟机栈&#xff09;2. 本地方法栈3. 程序计数器4. 方法区&#xff08;元空间&#xff09;5. 堆6、运行时常量池&#xff08;Runtime Constant Pool&#xff09;7、直接内存&#xff08;Direct Me…

QOpenGLWidget绘制实时图像

initializeGL()函数&#xff1a; initializeOpenGLFunctions();//创建VBO和VAO对象&#xff0c;并赋予IDglGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);//绑定VBO和VAO对象glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);//为当前绑定到target的缓冲…

如何将Word中的中文数字转化为阿拉伯数字

例如这种情况&#xff1a; 需要把这些汉字数字改为阿拉伯数字。 步骤1&#xff1a;在任意位置输入“第章”&#xff0c;然后把光标放到“第”和“章”的中间&#xff0c;然后ctrlf9插入域&#xff0c;在域里面输入 autonum&#xff0c;然后按altf9 显示域值。 按下altF9后 第 …

MySQL怎样删除重复数据,只保留一条?

在实际工作开发过程中&#xff0c;常常会遇到数据库表中存在多条数据重复了&#xff0c;此时我们需要删除重复数据&#xff0c;只保留其中一条有效的数据&#xff1b; 针对这种场景&#xff0c;我们用SQL语句该怎么实现呢&#xff1f; 数据准备 建表语句&#xff1a; DROP …

.ssh文件夹下缺失known_hosts文件

.ssh文件夹下缺失known_hosts文件 先确认工蜂或github 添加了git生成的密钥 然后 桌面打开git bash 1、执行ssh -T gitgitlab.com 2、输入yes

kafka架构和原理详解

Apache Kafka 是一个分布式流数据平台,用于高吞吐量、持久性、可扩展的发布和订阅消息。它具有高度的可靠性,被广泛用于构建实时数据流处理、日志收集和数据管道等应用。 基本架构 1. 主题(Topic): 主题是消息的逻辑分类生产者将消息发布到特定的主题中,而消费者可以订阅…

ssm+vue海鲜自助餐厅系统源码和论文

ssmvue海鲜自助餐厅系统源码和论文068 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&…

基于PID优化和矢量控制装置的四旋翼无人机(MatlabSimulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

嬴图Ultipa | 一文了解关于图数据库的一点儿干货

本篇包括以下内容点&#xff1a; 数据库主要技术分类 图是什么&#xff1f; 图的模式 图数据库 VS.关系型数据库 图数据库VS.其他NOSQL的对比 并非所有的图数据库都一样&#xff01; 根据Gartner预测&#xff0c;“到2025年&#xff0c;使用图技术进行数据和分析创新…

C# 生成唯一ID

1.首先通过nuget安装yitter.idgenerator 下面的三行代码搞定