四月十九号—leetcode刷题总结
题目一:108. 将有序数组转换为二叉搜索树
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
该日题集主要是熟悉二叉树的基础知识。通过递归取实现节点的遍历。
示例 1:
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
示例 2:
输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 按 严格递增 顺序排列
思路
nums严格单调递增,而我们所要构造的二叉树需要高度平衡,因此以数组的中点为数的根便满足题意,
以这棵树的根开始,不断向下延展,采用递归的方式.
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return helper(nums,0,nums.size()-1);
}
TreeNode* helper(vector<int>&nums,int left,int right)
{
if(left>right)
{
return nullptr;
}
int mid=(left+right)/2;
TreeNode *root=new TreeNode(nums[mid]);
root->left=helper(nums,left,mid-1);
root->right=helper(nums,mid+1,right);
return root;
}
};
题目二
144.二叉树的前序遍历
链接二叉树的前序遍历
此题为数据结构二叉树的遍历的入门题,其遍历共有三种方式,前序,后序,中序,其在代码上的区别无非是几个语句的顺序不一样。
前序,先存储根节点,再左节点,右节点。
使用递归一次遍历,root为空时返回。
使用c++中的vector存储更便利,直接push_back().
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int>nums;
find(root,nums);
return nums;
}
void find(TreeNode *root,vector<int>&nums)
{
if(!root)
return ;
nums.push_back(root->val);
find(root->left,nums);
find(root->right,nums);
}
};
中序遍历
二叉树的中序遍历
理解了前一道题,接下了便势如破竹
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int>nums;
find(root,nums);
return nums;
}
void find(TreeNode* root,vector<int>&nums)
{
if(!root)
return ;
find(root->left,nums);
nums.push_back(root->val);
find(root->right,nums);
}
};
题目三
后序遍历
额~~后序遍历
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int>nums;
find(root,nums);
return nums;
}
void find(TreeNode* root,vector<int>&nums)
{
if(!root)
return ;
find(root->left,nums);
find(root->right,nums);
nums.push_back(root->val);
}
};
题目四: 二叉树的最大深度
104求二叉树的最大深度
思路
因为是二叉树,顾每个节点只有两条路,只需选节点最多的路即可。
class Solution {
public:
int maxDepth(TreeNode* root) {
int ans=0;
ans=get(root);
return ans;
}
int get(TreeNode* root)
{
if(!root)
return 0;
int ans=1+max(get(root->left),get(root->right));
return ans;
}
};
题目五:验证二叉树的前序列化
验证二叉树的前序列化
序列化二叉树的一种方法是使用 前序遍历 。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
例如,上面的二叉树可以被序列化为字符串 “9,3,4,#,#,1,#,#,2,#,6,#,#”,其中 # 代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
保证 每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 ‘#’ 。
你可以认为输入格式总是有效的
例如它永远不会包含两个连续的逗号,比如 “1,3” 。
注意:不允许重建树。
示例 1:
输入: preorder = “9,3,4,#,#,1,#,#,2,#,6,#,#”
输出: true
示例 2:
输入: preorder = “1,#”
输出: false
示例 3:
输入: preorder = “9,#,#,1”
输出: false
思路:
当一个节点为空,输入了‘#’,则说明每个非空的节点都将带两节点(不论是否为空),为空便不带节点。那么当我们遍历完string时,节点也遍历完,若string以遍历完,但还空着节点,不能前序列化
第二,因其为前序遍历,我们先访问左子树,
因此采用栈来标记每一次的状态,即还可存几个节点(最多两个)
因为只需考虑此树的合法性,则只有数据的空与非空对操作有影响,而题目给的存储类型为string型,当其数字时,需一并读掉。
当一个非空节点已有两便出栈,不再进行考虑,
此时便出现了一个问题,当我们把栈弹空时,说明以所有数据已经满足1对2的条件,如果之后还有数据,则定不满足题意的二叉树。
将两种错误用黄色标记
代码:
class Solution {
public:
bool isValidSerialization(string preorder) {
int n=preorder.length();
int i=0;
stack<int>stk;
stk.push(1);
while(i<n)
{
if(stk.empty())
{
return false;
}
if(preorder[i]==',')
{
i++;
}
else if(preorder[i]=='#')
{
stk.top()-=1;
if(stk.top()==0)
{
stk.pop();
}
i++;
}
else
{
while(i<n&&preorder[i]!=',')
{
i++;
}
stk.top()-=1;
if(stk.top()==0)
{
stk.pop();
}
stk.push(2);
}
}
return stk.empty();
}
};
好了,刷题结束。