秋招突击——6/14——复习{(树形DP)树的最长路径}——新作{非递归求二叉树的深度、重复区间合并}

文章目录

    • 引言
    • 复习
      • 树形DP——树的最长路径
    • 新作
      • 使用dfs非递归计算二叉树的深度
      • 多个区间合并删除问题
        • 实现思路
        • 实现代码
        • 参考思路
    • 总结

引言

  • 这两天可能有点波动,但是算法题还是尽量保证复习和新作一块弄,数量上可能有所差别。

复习

树形DP——树的最长路径

  • 这道题是没有完全听完,但是到现在这个阶段,最起码得数组实现邻接链表做完。

无向图的一维数组表示邻接表实现

  • 首先说明一下,这里要使用邻接链表实现,这里是使用一维数组实现的邻接链表。
  • 同时这里是双向链表,所以,要加两次边,具体是实现如下

在这里插入图片描述

下面开始具体的分析

  • 树是一个确定的拓扑结构,每一个节点之间是是存在对应的父子关系,所以列觉路径可以更换为枚举中间节点,具体分析见下图,这是参考别人的,分析的很有道理

  • 通过红色节点的有三条路径

    • 红色路径,是一红色节点为根节点的最长的路径
    • 蓝色路径,是以红色节点为跟节点的最长路径和次长路径的和
    • 橙色路径,是红色节点的父节点的相同情况,具体见上图。
  • 相当于这道题,就是在遍历的过程中,计算对应的最长路径和子路径,然后在计算两者的和。

图片参考来源
在这里插入图片描述

动态规划分析

  • 这道题是两个动态规划,分别是动态规划计算最长的路径,次长的路径,而且是一个很明显的动态规划题目,就是子状态影响最终的状态。
  • 所以状态转移函数,就是计算的最长路径和次长路径,这里的动态规划,就是两个路径,f1[i]表示以节点i为根节点的最长路径,f2[i]表示以i为根节点的次长路径。具体如下

在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;const int N = 10010;
int h[N],e[2*N],ne[2*N],w[2*N],idx;
int f1[N],f2[N],res; // f1保存最长的转移路径,f2保存次长的转移路径
int n;void add(int a,int b,int c){e[idx] = b;w[idx] = c;ne[idx] = h[a];h[a] = idx ++;
}void dfs(int r,int father){// 这里r是对应的根节点,father是对应的父节点f1[r] = 0,f2[r] = 0;for (int i = h[r]; ~i; i = ne[i]) {int j = e[i];  // 确定子节点的编号if (j == father)    continue;dfs(j,r);if(f1[j] + w[i] >= f1[r]) f2[r] = f1[r],f1[r] = f1[j] + w[i];else if(f1[j] + w[i] > f2[r]) f2[r] = f1[j] + w[i];}res = max(res,f1[r] + f2[r]);
}int main(){cin>>n;// 构建无向图memset(h,-1,sizeof(h));for (int i = 0; i < n -1; ++i) {int a,b,c;cin>>a>>b>>c;add(a,b,c),add(b,a,c);}// 遍历对应的无向图for (int i = h[1]; ~i; i = ne[i]) {cout<<1<<"  "<<e [i]<<endl;}cout<<res;return 0;
}
  • 这道题拖了那么久,乍一看,其实还是蛮简单的,思路只要清楚了,后续还是很好实现的,然后那个使用一维数组实现的邻接链表的,之前是没有做过,现在知道怎么用了,还是蛮简单的。

新作

使用dfs非递归计算二叉树的深度

  • dfs非递归二叉树高度,一开始写了个经典队列的bfs,意识到不对后开始改,最后没改完,就说了个暴力找到每个叶子的高度的思路。

  • 这个忘记的有点多,如果单纯使用栈来实现的话,就需要每一次入栈当前节点的子节点还有对应的深度,然后出栈,如果是叶子节点,就比较一下长度,如果不是,就继续做出栈和入栈的操作。

  • 这里实现的基本上和我写的比较类似

#include <iostream>
#include <stack>using namespace std;struct TreeNode{int val;TreeNode* left;TreeNode* right;TreeNode(int x):val(x),left(NULL),right(NULL){};
};// 生成样例
TreeNode* createSampleTree1() {TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);root->right->right = new TreeNode(6);root->left->left->left = new TreeNode(7);return root;
}int treeHeight(TreeNode* root){// 使用非递归的方式计算的树深度stack<pair<TreeNode *,int>> s;// 根节点入栈并重置深度s.push({root,1});int r = 0;// 出栈并遍历每一个节点的子节点while(!s.empty()){TreeNode* t = s.top().first;int l = s.top().second;s.pop();// 判定左子节点是否为空if (t->left)    s.push({t->left,l + 1});if (t->right)    s.push({t->right,l + 1});// 比较深度r = max(r,l);}return r;
}int main(){TreeNode* root = createSampleTree1();cout<<treeHeight(root);
}
  • 参考方法
    • 这里指的学习的是一个auto的使用,通过下述方式可以直接进行遍历使用。
auto [node, depth] = stack.top();
#include <iostream>
#include <stack>
#include <algorithm> // for maxstruct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};int treeHeight(TreeNode* root) {if (root == nullptr) return 0;std::stack<std::pair<TreeNode*, int>> stack;stack.push({root, 1});int maxHeight = 0;while (!stack.empty()) {auto [node, depth] = stack.top();stack.pop();if (node != nullptr) {maxHeight = std::max(maxHeight, depth);if (node->left != nullptr) stack.push({node->left, depth + 1});if (node->right != nullptr) stack.push({node->right, depth + 1});}}return maxHeight;
}int main() {// 示例二叉树TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);std::cout << "树的高度是: " << treeHeight(root) << std::endl;// 清理内存delete root->left->left;delete root->left->right;delete root->left;delete root->right;delete root;return 0;
}

多个区间合并删除问题

  • 这个也是在网上搜索的,部分拼多多主管面可能问到的题目,所以这里做一下,具体题目描述如下
给定一个n×2的二维数组,数组的每一行代表一个区间,
如果一个区间被另一个区间包含就删掉该区间,返回剩
下的所有区间。
* 比如: [1 2][1 ,3]包含。
实现思路
  • 这里是使用自定义排序实现的,如果包含关系,就将之按照包含的关系进行排序,然后在进行从前往后逐步进行遍历,对于相同的数组直接去除。最后剩下的就是对应的元素。
  • 自定义排序实现贪婪算法!
  • 这个方法确实是有问题的,有一部分样例是没有考虑到,不过背一下这个模版的。
实现代码
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;using Interval = pair<int,int>;vector<Interval> removeContainedIntervals(vector<Interval>& intervals){// 可以对区间进行排序,按照包含关系进行排序vector<Interval> res;sort(intervals.begin(),intervals.end(),[](auto a,auto b){if(a.first <= b.first && a.second >= b.second)    return 1;else return 0;});for (int i = 0;i < intervals.size();i ++) {Interval t = intervals[i];res.push_back(t);while((i + 1 < intervals.size())&& t.first <= intervals[i+1].first&& t.second >= intervals[i+1].second)i ++;}return res;
}int main() {vector<vector<Interval>> samples = {{{1, 4}, {2, 3}, {1, 3}, {4, 6}, {5, 7}},
//            {{1, 5}, {2, 4}, {6, 8}, {7, 9}, {5, 10}},
//            {{1, 2}, {3, 4}, {2, 3}, {1, 5}, {6, 7}},
//            {{1, 2}, {2, 3}, {3, 4}, {4, 5}},
//            {{1, 3}, {2, 6}, {8, 10}, {15, 18}}};for (size_t i = 0; i < samples.size(); ++i) {vector<Interval> result = removeContainedIntervals(samples[i]);cout << "样例 " << i + 1 << " 剩余的区间为:" << endl;for (const auto& interval : result) {cout << "[" << interval.first << ", " << interval.second << "] ";}cout << endl;}return 0;
}
参考思路
  • 这里是一个贪心算法解决区间问题的模板,需要好好练习一下,和我的方法差不多,只不过他是针对单边进行排序的
  • 这里是使用标准区间进行比较的,会更加灵活方便一点,比我的方法要好很多。
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;// 定义一个区间类型
using Interval = pair<int, int>;// 比较函数,用于排序区间
bool compareIntervals(const Interval &a, const Interval &b) {if (a.first == b.first) {return a.second < b.second;}return a.first < b.first;
}vector<Interval> removeContainedIntervals(vector<Interval>& intervals) {// 如果区间列表为空,直接返回空列表if (intervals.empty()) {return {};}// 按照起始点排序,起始点相同则按照终止点排序sort(intervals.begin(), intervals.end(), compareIntervals);vector<Interval> result;Interval last = intervals[0]; // 初始化第一个区间作为比较基准for (size_t i = 1; i < intervals.size(); ++i) {// 如果当前区间不被上一个区间包含if (intervals[i].first > last.first && intervals[i].second > last.second) {result.push_back(last); // 保留上一个区间last = intervals[i];    // 更新比较基准} else {// 如果当前区间的终止点更长,更新比较基准if (intervals[i].second > last.second) {last = intervals[i];}}}// 最后一个区间也需要保留result.push_back(last);return result;
}int main() {vector<vector<Interval>> samples = {{{1, 4}, {2, 3}, {1, 3}, {4, 6}, {5, 7}},{{1, 5}, {2, 4}, {6, 8}, {7, 9}, {5, 10}},{{1, 2}, {3, 4}, {2, 3}, {1, 5}, {6, 7}},{{1, 2}, {2, 3}, {3, 4}, {4, 5}},{{1, 3}, {2, 6}, {8, 10}, {15, 18}}};for (size_t i = 0; i < samples.size(); ++i) {vector<Interval> result = removeContainedIntervals(samples[i]);cout << "样例 " << i + 1 << " 剩余的区间为:" << endl;for (const auto& interval : result) {cout << "[" << interval.first << ", " << interval.second << "] ";}cout << endl;}return 0;
}

总结

  • 复习的那个最长路径,还是蛮简单的,今天终于看懂了,继续加油吧。明天可以快速写一下。
  • 今天算是做了两道新的题目,dfs获取树的深度那道题,是自己做出来的,然后区间合并的那道题,是参考别人的,不过看了题解,加油吧!明天把题目再过一遍!

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

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

相关文章

React state(及组件) 的保留与重置

当在树中相同的位置渲染相同的组件时&#xff0c;React 会一直保留着组件的 state return (<div><Counter />{showB && <Counter />} </div> ) // 当 showB 为 false, 第二个计数器停止渲染&#xff0c;它的 state 完全消失了。这是因为 React…

vite.config.js如何使用env的环境变量

了解下环境变量在vite中 官方文档走起 https://cn.vitejs.dev/guide/env-and-mode.html#env-variables-and-modes 你见到的.env,.env.production等就是放置环境变量的 官方文档说到.env.[mode] # 只在指定模式下加载,比如.env.development只在开发环境加载 至于为什么是deve…

windows下open webui+ollama+sd webui

原文&#xff1a;https://wangguo.site/Blog/2024/Q2/2024-06-14/ 说明&#xff1a;安装使用环境是在Windows下 1、给ollama一个好看的交互界面&#xff08;open webui&#xff09; 1.1、ollama安装 安装&#xff1a;在ollama官网下载windows版本进行安装 模型列表&#xff1…

【SQLAlChemy】表之间的关系,外键如何使用?

表之间的关系 数据库表之间的关系分为三种&#xff1a; 一对一关系&#xff08;One-to-One&#xff09;&#xff1a;在这种关系中&#xff0c;表A的每一行都与表B的一行关联&#xff0c;反之亦然。例如&#xff0c;每个人都有一个唯一的社保号&#xff0c;每个社保号也只属于…

南师大GIS专业2024排名NO.1!!!

南师大GIS 666 学科专业实力666&#xff0c;研究方向多多多&#xff01; 有学术方向有开发应用方向&#xff0c; 有GIS&#xff08;建模、数字地形、基础理论和三维GIS等&#xff09;、 有Cartography &#xff08;叙事地图、动态地图、地图风格迁移等&#…

Visual Studio Code 的安装教程和配置C语言环境插件推荐

目录 1.vscode简介2.下载安装vs code3.VSCode基础配置VSCode界面简介VSCode设置中文界面VSCode个性化设置VSCode常用设置基本编辑快捷键VSCode常用快捷键 4.下载安装MinGW5.设置vscode里的环境6.插件推荐7.vscode官方文档 1.vscode简介 VSCode是微软出的一款轻量级编辑器&…

Javaweb03-Servlet技术1(Servlet,ServletConfig,ServletContext)

Servlet技术(Servlet,ServletConfig,ServletContext) 1.Servlet的概述 Servlet是运行在Web服务器端的Java应用程序&#xff0c;它使用Java语言编写。与Java程序的区别是&#xff0c;Servlet 对象主要封装了对HTTP请求的处理&#xff0c;并且它的运行需要Servlet容器(Tomcat)的…

人工智能历史与现状

1 人工智能历史与现状 1.1 人工智能的概念和起源 1.1.1 人工智能的概念 人工智能 (Artificial Intelligence ,AI)是一门研究如何使计算机 能够模拟人类智能行为的科学和技术,目标在于开发能够感知、理解、 学习、推理、决策和解决问题的智能机器。人工智能的概念主要包含 以…

vivado HW_TARGET

HW_目标 描述 硬件目标hw_target是包含一个或多个JTAG链的系统板 Xilinx FPGA设备&#xff0c;您可以使用比特流文件进行编程&#xff0c;或用于调试您的设计。 系统板上的硬件目标与Vivado Design Suite之间的连接 由硬件服务器对象hw_server管理。 使用open_hw_target命令打开…

StableSwarmUI 安装教程(详细)

文章目录 背景特点安装 背景 StableSwarmUI是StabilityAI官方开源的一个文生图工作流UI&#xff0c;目前处于beta阶段&#xff0c;但主流程是可以跑通的。该UI支持接入ComfyUI、Stable Diffusion-WebUI。其工作原理就是使用ComfyUI、Stable Diffusion-WebUI或者StabilityAI官方…

利用系统或软件缺陷进行攻击

操作系统都有漏洞 这里就是输入的字符串长度太长了 超过8个字节了 没听懂

在下游市场需求带动下 我国聚天门冬氨酸脂防腐涂料市场规模不断扩大

在下游市场需求带动下 我国聚天门冬氨酸脂防腐涂料市场规模不断扩大 聚天门冬氨酸酯防腐涂料又称为天冬聚脲防腐涂料&#xff0c;是以聚天门冬氨酸酯作为主体树脂、脂肪族异氰酸酯为固化剂而形成的一种防腐涂料。与其他类型的防腐涂料相比&#xff0c;聚天门冬氨酸酯防腐涂料具…

【Hive下篇: 一篇文章带你了解表的静态分区,动态分区! 分桶!Hive sql的内置函数!复杂数据类型!hive的简单查询语句!】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;本篇文章主要分享的是大数据开发中hive的相关技术。连接查询&#xff01;正则表达式&#xff01; 虚拟列&#xff01;爆炸函数&#xff01;行列转换&#xff01; Hive的数据压缩和数据存储…

利用穿戴甲虚拟试戴技术提高销量和参与度

在不断变化的美容行业&#xff0c;保持领先意味着拥抱创新技术。其中一项改变游戏规则的技术是人工智能驱动的虚拟指甲试戴。在穿戴甲领域&#xff0c;不断兴起的虚拟试戴技术对促进销售和参与度产生了重大影响。 视觉吸引力的力量 要了解虚拟试戴的重要性&#xff0c;必须了解…

简单了解MySql以及一些简单的应用MySql

MySql基础篇 1、数据模型概述 关系型数据库 概念&#xff1a;建立在关系模型基础上&#xff0c;由多张相互连接的二维表组成的数据库。 特点&#xff1a; 使用表存储数据&#xff0c;格式统一&#xff0c;便于维护使用SQL语言操作&#xff0c;标准统一&#xff0c;使用方便 数…

基于hispark_taurus开发板示例学习OpenHarmony编译构建系统(2)

3、hispark_taurus产品解决方案-Vendor 产品解决方案为基于开发板的完整产品&#xff0c;主要包含产品对OS的适配、组件拼装配置、启动配置和文件系统配置等。产品解决方案的源码路径规则为&#xff1a;vendor/{产品解决方案厂商}/{产品名称}_。_产品解决方案也是一个特殊的组…

vue生命周期及组件讲解(如何导入引用外部vue文件,以及注册全局变量,自定义标签效果)

生命周期钩子的理解与应用 函数说明onBeforeMount( )组件挂载前onMounted( )组件挂载后onBeforeUpdate( )组件更新前onUpdated( )组件中任意的DOM元素更新后onBeforeUnmount( )组件实例被销毁前onUnmounted( )组件实例被销毁后 生命周期在 各类应用以及网站中使用非常广泛&…

k8s+springboot+redis部署配置连接

1 springboot 配置k8s中的redis服务名 #tomcat访问端口 # 应用名称 spring.application.namedemo # 应用服务Web访问端口 server.port8089 server.envtest #缓存关闭 spring.thymeleaf.cachefalse #可选配置 management.endpoints.enabled-by-defaulttrue management.endpoint…

springboot与flowable(6):任务分配(监听器)

一、创建流程模型 制作如下流程 给审批用户1一个值表达式。 二、给用户审批2添加监听器 创建一个监听器类 package org.example.flowabledemo2.listener;import org.flowable.engine.delegate.TaskListener; import org.flowable.task.service.delegate.DelegateTask;/*** 自定…

【PLG洞察】|向Figma学习如何打造标杆客户和实施分销策略

Figma是一款功能强大的在线协同设计工具&#xff0c;它主要被用于界面设计、原型设计和用户体验设计。作为国外知名的saas企业&#xff0c;对标国内的saas蓝海&#xff0c;它的增长实在惊人&#xff01;据称&#xff0c;Figma2020年的收入已达$75M, 2021年6月&#xff0c;美国的…