当前位置: 首页 > news >正文

成都正规小程序开发公司seo网站优化助理

成都正规小程序开发公司,seo网站优化助理,深圳品牌网站制作公司,鄂州网站设计制作作者推荐 动态规划LeetCode2552:优化了6版的1324模式 题目 给你 n 个 二叉搜索树的根节点 ,存储在数组 trees 中(下标从 0 开始),对应 n 棵不同的二叉搜索树。trees 中的每棵二叉搜索树 最多有 3 个节点 &#xff0…

作者推荐

动态规划LeetCode2552:优化了6版的1324模式

题目

给你 n 个 二叉搜索树的根节点 ,存储在数组 trees 中(下标从 0 开始),对应 n 棵不同的二叉搜索树。trees 中的每棵二叉搜索树 最多有 3 个节点 ,且不存在值相同的两个根节点。在一步操作中,将会完成下述步骤:
选择两个 不同的 下标 i 和 j ,要求满足在 trees[i] 中的某个 叶节点 的值等于 trees[j] 的 根节点的值 。
用 trees[j] 替换 trees[i] 中的那个叶节点。
从 trees 中移除 trees[j] 。
如果在执行 n - 1 次操作后,能形成一棵有效的二叉搜索树,则返回结果二叉树的 根节点 ;如果无法构造一棵有效的二叉搜索树,返回 null 。
二叉搜索树是一种二叉树,且树中每个节点均满足下述属性:
任意节点的左子树中的值都 严格小于 此节点的值。
任意节点的右子树中的值都 严格大于 此节点的值。
叶节点是不含子节点的节点。
示例 1:
输入:trees = [[2,1],[3,2,5],[5,4]]
输出:[3,2,5,1,null,4]
解释:
第一步操作中,选出 i=1 和 j=0 ,并将 trees[0] 合并到 trees[1] 中。
删除 trees[0] ,trees = [[3,2,5,1],[5,4]] 。
在第二步操作中,选出 i=0 和 j=1 ,将 trees[1] 合并到 trees[0] 中。
删除 trees[1] ,trees = [[3,2,5,1,null,4]] 。
结果树如上图所示,为一棵有效的二叉搜索树,所以返回该树的根节点。
示例 2:
输入:trees = [[5,3,8],[3,2,6]]
输出:[]
解释:
选出 i=0 和 j=1 ,然后将 trees[1] 合并到 trees[0] 中。
删除 trees[1] ,trees = [[5,3,8,2,6]] 。
结果树如上图所示。仅能执行一次有效的操作,但结果树不是一棵有效的二叉搜索树,所以返回 null 。
示例 3:
输入:trees = [[5,4],[3]]
输出:[]
解释:无法执行任何操作。
参数范围
n == trees.length
1 <= n <= 5 * 104
每棵树中节点数目在范围 [1, 3] 内。
输入数据的每个节点可能有子节点但不存在子节点的子节点
trees 中不存在两棵树根节点值相同的情况。
输入中的所有树都是 有效的二叉树搜索树 。
1 <= TreeNode.val <= 5 * 104.

分析

正确分析

能合并则合并,如果合并树的数量为1,则正确。
不需要考虑:叶子相同,那个叶子合并根的问题,两个叶子相同,那个叶子合并最后都不会是合法的搜索树。

错误分析

vMin 记录各子树的最小值,vMax记录各子树的最大值。 成为左子树的条件:一,叶子的值等子树根的值。 二,子树的最大值小于父树的值。成为右子树的条件:一,叶子的值等子树根的值。 二,子树的最小值大于父树的值。

错误原因

父子符合条件,祖孙不符合条件。

解决方法

判断是否是合法的树。

变量解释

vMin[i]以trees[i]为根的树的最小节点值
vMax[i]以trees[i]为根的树的最大节点值
mValueIndexkey:trees[i]根节点的值;value:i。

代码

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* canMerge(vector<TreeNode*>& trees) {
m_c = trees.size();
vector vMin(m_c), vMax(m_c);
unordered_map<int, int> mValueIndex;
for (int i = 0; i < m_c; i++)
{
const auto& p = trees[i];
mValueIndex[p->val] = i;
vMin[i] = (nullptr == p->left) ? p->val : p->left->val;
vMax[i] = (nullptr == p->right) ? p->val : p->right->val;
}
for (int i = 0; i < m_c; i++)
{
std::cout << "i " << i;
const auto& p = trees[i];
if ((nullptr != p->left) && mValueIndex.count(p->left->val))
{
const int index = mValueIndex[p->left->val];
if (vMax[index] < p->val)
{
std::cout << "index " << index;
vMin[i] = min(vMin[i], vMin[index]);
p->left = trees[index];
mValueIndex.erase(mValueIndex.find(p->left->val));
}
}
if ((nullptr != p->right) && mValueIndex.count(p->right->val))
{
const int index = mValueIndex[p->right->val];
if (vMin[index] > p->val)
{
std::cout << "r " << index;
vMax[i] = max(vMax[i], vMax[index]);
p->right = trees[index];
mValueIndex.erase(p->right->val);
}
}
std::cout << std::endl;
}
if (mValueIndex.size() > 1) return nullptr;
auto [suc, tmp1, tmp2] = DFS(trees[mValueIndex.begin()->second]);
if (!suc)
{
return nullptr;
}
return trees[mValueIndex.begin()->second];
}
std::tuple<bool, int, int> DFS(TreeNode* root)
{
int iMin = root->val;
int iMax = root->val;
if (nullptr != root->left)
{
auto [suc, iRetMin, iRetMax] = DFS(root->left);
if ((!suc)||( iRetMax >= root->val))
{
return std::make_tuple(false, 0, 0);
}
iMin = iRetMin;
}
if (nullptr != root->right)
{
auto [suc, iRetMin, iRetMax] = DFS(root->right);
if ((!suc) || (iRetMin <= root->val))
{
return std::make_tuple(false, 0, 0);
}
iMax = iRetMax;
}
return std::make_tuple(true, iMin, iMax);
}
int m_c;
};

优化

分析

最后总是要判断是否是合法树,那合并树的时候就不需要判断了。这样会产生新问题:
三个子树成环,两个子树合并成树。 合并了3次符合条件,但不是一棵树,而是两个连通区域。
解法方法如下:
一,判断唯一的树的节点数是否合法。
二,并集查找,看有几个连通区域。
三,判断有几个合法的根(不存在值相同的叶子),从根开始合并。
四,获取树的中顺遍历,看是否是严格递增。且节点数是否正确。

判断合法的根的代码

class Solution {
public:
TreeNode* canMerge(vector<TreeNode*>& trees) {
m_c = trees.size();
unordered_set setLeaf;
for (int i = 0; i < m_c; i++)
{
auto& p = trees[i];
m_mValuePtr[p->val] = p;
if (nullptr != p->left)
{
setLeaf.emplace(p->left->val);
}
if (nullptr != p->right)
{
setLeaf.emplace(p->right->val);
}
}
TreeNode* root = nullptr;
for (int i = 0; i < m_c; i++)
{
if (setLeaf.count(trees[i]->val))
{
continue;//和某个叶子起点重合,不是根
}
if (nullptr != root)
{
return nullptr;//不可能有两个根
}
root = trees[i];
}
if( nullptr == root)
{
return nullptr;
}
DFSBuild(root);
if (m_mValuePtr.size() != 1 )
{
return nullptr;
}
auto [suc, tmp1, tmp2] = DFS(root);
if (!suc)
{
return nullptr;
}
return root;
}
void DFSBuild(TreeNode* root)
{
auto Build = [&](TreeNode*& node)
{
if ((nullptr != node) && (m_mValuePtr.count(node->val)))
{
node = m_mValuePtr[node->val];
m_mValuePtr.erase(node->val);
DFSBuild(node);
}
};
Build(root->left);
Build(root->right);
}
std::tuple<bool, int, int> DFS(TreeNode* root)
{
int iMin = root->val;
int iMax = root->val;
if (nullptr != root->left)
{
auto [suc, iRetMin, iRetMax] = DFS(root->left);
if ((!suc) || (iRetMax >= root->val))
{
return std::make_tuple(false, 0, 0);
}
iMin = iRetMin;
}
if (nullptr != root->right)
{
auto [suc, iRetMin, iRetMax] = DFS(root->right);
if ((!suc) || (iRetMin <= root->val))
{
return std::make_tuple(false, 0, 0);
}
iMax = iRetMax;
}
return std::make_tuple(true, iMin, iMax);
}
unordered_map<int, TreeNode*> m_mValuePtr;
int m_c;
};

中序遍历

class Solution {
public:
TreeNode* canMerge(vector<TreeNode*>& trees) {
m_c = trees.size();
int iNodeCount = 0;
for (int i = 0; i < m_c; i++)
{
const auto& p = trees[i];
m_mValuePtr[p->val] = p;
iNodeCount += (1 + (nullptr != p->left) + (nullptr != p->right));
}
for (int i = 0; i < m_c; i++)
{
auto Build = [&](TreeNode*& node)
{
if ((nullptr != node) && (m_mValuePtr.count(node->val)))
{
node = m_mValuePtr[node->val];
m_mValuePtr.erase(node->val);
}
};
Build(trees[i]->left);
Build(trees[i]->right);
}
if (m_mValuePtr.size() != 1 )
{
return nullptr;
}
vector vNode;
DFSNLR(vNode, m_mValuePtr.begin()->second);
if (vNode.size() + m_c-1 != iNodeCount)
{
return nullptr;
}
for (int i = 1; i < vNode.size(); i++)
{
if (vNode[i] <= vNode[i - 1])
{
return nullptr;
}
}
return m_mValuePtr.begin()->second;
}
void DFSNLR(vector& v,TreeNode* root)
{
if (nullptr == root)
{
return ;
}
DFSNLR(v,root->left);
v.emplace_back(root->val);
DFSNLR(v,root->right);
}
unordered_map<int, TreeNode*> m_mValuePtr;
int m_c;
};

中序遍历优化

vNode我们只需要读取最后一个值,所以可以用一个整形变量pre代替。

 class Solution {public:TreeNode* canMerge(vector<TreeNode*>& trees) {m_c = trees.size();int iNodeCount = 0;for (int i = 0; i < m_c; i++){const auto& p = trees[i];m_mValuePtr[p->val] = p;iNodeCount += (1 + (nullptr != p->left) + (nullptr != p->right));}for (int i = 0; i < m_c; i++){auto Build = [&](TreeNode*& node){if ((nullptr != node) && (m_mValuePtr.count(node->val))){node = m_mValuePtr[node->val];m_mValuePtr.erase(node->val);		}};Build(trees[i]->left);Build(trees[i]->right);}if (m_mValuePtr.size() != 1 ){return  nullptr;}int pre=-1;if (!DFSNLR(m_mValuePtr.begin()->second, pre) || (m_iNodeSize + m_c - 1 != iNodeCount)){return nullptr;}return m_mValuePtr.begin()->second;}bool DFSNLR(TreeNode* root, int& pre){if ((root->left) && (!DFSNLR(root->left, pre))){return false;}m_iNodeSize++;if (root->val <= pre){return false;}pre = root->val;if ((root->right) && (!DFSNLR(root->right, pre))){return false;}return true;}	   int m_iNodeSize = 0;unordered_map<int, TreeNode*> m_mValuePtr;int m_c;};

2023年6月旧版

class Solution {
public:
TreeNode* canMerge(vector<TreeNode*>& trees) {
vector<TreeNode*> vRoot(5 * 10000 + 1);
std::set setNums;
for (auto& ptr : trees)
{
vRoot[ptr->val] = ptr;
setNums.emplace(ptr->val);
if (nullptr != ptr->left)
{
setNums.emplace(ptr->left->val);
}
if (nullptr != ptr->right)
{
setNums.emplace(ptr->right->val);
}
}
int iNodeNum = setNums.size();
for (auto& ptr : trees)
{
if ((nullptr != ptr->left) && (nullptr != vRoot[ptr->left->val]))
{
ptr->left = vRoot[ptr->left->val];
vRoot[ptr->left->val] = nullptr;
}
if ((nullptr != ptr->right) && (nullptr != vRoot[ptr->right->val]))
{
ptr->right = vRoot[ptr->right->val];
vRoot[ptr->right->val] = nullptr;
}
}
TreeNode* pRoot = nullptr;
for (auto ptr : vRoot)
{
if (nullptr == ptr)
{
continue;
}
if (nullptr != pRoot)
{
return nullptr;//两个根
}
pRoot = ptr;
}
if (nullptr == pRoot)
{
return nullptr;
}
if (iNodeNum != DFSNum(pRoot))
{
return nullptr;
}
int iMin, iMax;
bool bRet = DFS(iMin, iMax, pRoot);
return bRet ? pRoot : nullptr;
}
bool DFS(int& iMin, int& iMax, TreeNode* pNode)
{
iMin = iMax = pNode->val;
if ((nullptr != pNode->left))
{
int iMinLeft, iMaxLeft;
if (!DFS(iMinLeft, iMaxLeft, pNode->left))
{
return false;
}
if (iMaxLeft >= pNode->val)
{
return false;
}
iMin = iMinLeft;
}
if ((nullptr != pNode->right))
{
int iMinRight, iMaxRight;
if (!DFS(iMinRight, iMaxRight, pNode->right))
{
return false;
}
if (iMinRight <= pNode->val)
{
return false;
}
iMax = iMaxRight;
}
return true;
}
int DFSNum(TreeNode* pNode)
{
if (nullptr == pNode)
{
return 0;
}
return 1 + DFSNum(pNode->left) + DFSNum(pNode->right);
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境:

VS2022 C++17


文章转载自:
http://dinncoverbosely.ydfr.cn
http://dinncohighbinder.ydfr.cn
http://dinncoqualifiable.ydfr.cn
http://dinncoheartache.ydfr.cn
http://dinncophotosynthesize.ydfr.cn
http://dinncotomboyish.ydfr.cn
http://dinncopedalo.ydfr.cn
http://dinncodiaper.ydfr.cn
http://dinncofloridan.ydfr.cn
http://dinncomullah.ydfr.cn
http://dinncocosmopolitism.ydfr.cn
http://dinncoclootie.ydfr.cn
http://dinncodemilitarise.ydfr.cn
http://dinncomonofile.ydfr.cn
http://dinncoichthyic.ydfr.cn
http://dinncometempirical.ydfr.cn
http://dinncolevallorphan.ydfr.cn
http://dinncopuromycin.ydfr.cn
http://dinncomacrolepidopteron.ydfr.cn
http://dinncoplaneside.ydfr.cn
http://dinncofulgurating.ydfr.cn
http://dinncoapocatastasis.ydfr.cn
http://dinncopsychology.ydfr.cn
http://dinncotzaristic.ydfr.cn
http://dinncoretinaculum.ydfr.cn
http://dinncobackfill.ydfr.cn
http://dinncodamoclean.ydfr.cn
http://dinncotravois.ydfr.cn
http://dinncoknifeboard.ydfr.cn
http://dinncomaist.ydfr.cn
http://dinncoinextricability.ydfr.cn
http://dinncodepilate.ydfr.cn
http://dinncooscillometer.ydfr.cn
http://dinncomotivator.ydfr.cn
http://dinncomeet.ydfr.cn
http://dinncocove.ydfr.cn
http://dinncococker.ydfr.cn
http://dinncochromatography.ydfr.cn
http://dinncopuritanism.ydfr.cn
http://dinncoladder.ydfr.cn
http://dinncoreadableness.ydfr.cn
http://dinncogibson.ydfr.cn
http://dinncowidowhood.ydfr.cn
http://dinncoarenose.ydfr.cn
http://dinncomicromere.ydfr.cn
http://dinncokilimanjaro.ydfr.cn
http://dinncolooker.ydfr.cn
http://dinncogravisphere.ydfr.cn
http://dinncocowper.ydfr.cn
http://dinncoslid.ydfr.cn
http://dinncobicyclist.ydfr.cn
http://dinncofabular.ydfr.cn
http://dinncocobaltiferous.ydfr.cn
http://dinncotuvaluan.ydfr.cn
http://dinncoredigest.ydfr.cn
http://dinncoknifepoint.ydfr.cn
http://dinncopunctulated.ydfr.cn
http://dinncofluvial.ydfr.cn
http://dinncotrustiness.ydfr.cn
http://dinncooverhigh.ydfr.cn
http://dinncompu.ydfr.cn
http://dinncoovergrowth.ydfr.cn
http://dinncoscheduler.ydfr.cn
http://dinncoroofline.ydfr.cn
http://dinncogorgy.ydfr.cn
http://dinncomispronounce.ydfr.cn
http://dinncotrihydrate.ydfr.cn
http://dinncoivba.ydfr.cn
http://dinncoheading.ydfr.cn
http://dinncothirstily.ydfr.cn
http://dinncomastoidean.ydfr.cn
http://dinncoterminer.ydfr.cn
http://dinncoairspeed.ydfr.cn
http://dinncooe.ydfr.cn
http://dinncoearthly.ydfr.cn
http://dinncocherenkov.ydfr.cn
http://dinncosicklebill.ydfr.cn
http://dinncolavvy.ydfr.cn
http://dinncobottomland.ydfr.cn
http://dinncoproscription.ydfr.cn
http://dinncoamendment.ydfr.cn
http://dinncobetting.ydfr.cn
http://dinncomutograph.ydfr.cn
http://dinncostyli.ydfr.cn
http://dinncolaterize.ydfr.cn
http://dinncoformatting.ydfr.cn
http://dinncoelusively.ydfr.cn
http://dinncoorganisation.ydfr.cn
http://dinncobackbiter.ydfr.cn
http://dinncoadolescent.ydfr.cn
http://dinncodowdily.ydfr.cn
http://dinncoentreaty.ydfr.cn
http://dinncounipetalous.ydfr.cn
http://dinncoissuer.ydfr.cn
http://dinncotritiated.ydfr.cn
http://dinncotentability.ydfr.cn
http://dinncocomte.ydfr.cn
http://dinncochylify.ydfr.cn
http://dinncolamby.ydfr.cn
http://dinncosparsely.ydfr.cn
http://www.dinnco.com/news/153696.html

相关文章:

  • 网站平台怎么建立的手机访问另一部手机访问文件
  • 网站文章伪原创怎么做百度站长工具app
  • 做视频网站需要哪些技术网站seo收录工具
  • wordpress 点踩成都官网seo费用
  • 官方网站建设银行信用卡刷评论网站推广
  • 蓝杉互动网站建设上海谷歌seo
  • 珠海建设网站的公司百度搜索量最大的关键词
  • 朝阳专业网站建设公司百度资源搜索平台
  • 网站的备案流程推广品牌
  • 辽宁建设信息网站电脑培训学校学费多少
  • thinkphp 企业网站源码seo关键词排名优化官网
  • 太原软件行业上海关键词排名优化价格
  • 县志中关于政府网站建设的网站测速工具
  • 哪些网站是用python做的网络营销五种方法
  • 北京网站设计精选刻百度seo快速排名
  • 哪些网站开业做简单海报网店运营入门基础知识
  • iapp如何用网站做软件怎么恶意点击对手竞价
  • 网站两侧对联广告图片教育培训网站设计
  • 信誉好的低价网站建设广州网络营销
  • 三网合一网站建设系统 价格西安疫情最新消息
  • 绵阳建设网站营销策划机构
  • 珠海seo网站建设百度地图人工电话
  • 搭建网站大概需要多少钱百度获客平台怎么收费的
  • 营销导向企业网站策划百度seo推广价格
  • 百度推广渠道商深圳网站营销seo费用
  • 建设企业网站所遵循的一般原则优化营商环境的意义
  • 做音乐网站建设的开发平台滕州seo
  • 南阳网网站建设软件定制开发平台
  • 网站建设与管理难学吗医院营销策略的具体方法
  • 公司制作网站怎么做的在线排名优化