LeetCode 每日一题 Day 88 - 94

2673. 使二叉树所有路径值相等的最小代价

给你一个整数 n 表示一棵 满二叉树 里面节点的数目,节点编号从 1 到 n 。根节点编号为 1 ,树中每个非叶子节点 i 都有两个孩子,分别是左孩子 2 * i 和右孩子 2 * i + 1 。

树中每个节点都有一个值,用下标从 0 开始、长度为 n 的整数数组 cost 表示,其中 cost[i] 是第 i + 1 个节点的值。每次操作,你可以将树中 任意 节点的值 增加 1 。你可以执行操作 任意 次。

你的目标是让根到每一个 叶子结点 的路径值相等。请你返回 最少 需要执行增加操作多少次。

注意:

满二叉树 指的是一棵树,它满足树中除了叶子节点外每个节点都恰好有 2 个子节点,且所有叶子节点距离根节点距离相同。
路径值 指的是路径上所有节点的值之和。

示例 1:
在这里插入图片描述

输入:n = 7, cost = [1,5,2,2,3,3,1]
输出:6
解释:我们执行以下的增加操作:

  • 将节点 4 的值增加一次。
  • 将节点 3 的值增加三次。
  • 将节点 7 的值增加两次。
    从根到叶子的每一条路径值都为 9 。
    总共增加次数为 1 + 3 + 2 = 6 。
    这是最小的答案。
    示例 2:

在这里插入图片描述

输入:n = 3, cost = [5,3,3]
输出:0
解释:两条路径已经有相等的路径值,所以不需要执行任何增加操作。

提示:

3 <= n <= 1e5
n + 1 是 2 的幂
cost.length == n
1 <= cost[i] <= 1e4
以数组形式给出的树,对数组进行遍历相当于自底向上对树进行遍历:

class Solution {
public:int minIncrements(int n, vector<int>& cost) {int ans = 0;for (int i = n - 2; i > 0; i -= 2) {ans += abs(cost[i] - cost[i + 1]);cost[i / 2] += max(cost[i], cost[i + 1]);}return ans;}
};

2581. 统计可能的树根数目(Hard)

Alice 有一棵 n 个节点的树,节点编号为 0 到 n - 1 。树用一个长度为 n - 1 的二维整数数组 edges 表示,其中 edges[i] = [ai, bi] ,表示树中节点 ai 和 bi 之间有一条边。

Alice 想要 Bob 找到这棵树的根。她允许 Bob 对这棵树进行若干次 猜测 。每一次猜测,Bob 做如下事情:

选择两个 不相等 的整数 u 和 v ,且树中必须存在边 [u, v] 。
Bob 猜测树中 u 是 v 的 父节点 。
Bob 的猜测用二维整数数组 guesses 表示,其中 guesses[j] = [uj, vj] 表示 Bob 猜 uj 是 vj 的父节点。

Alice 非常懒,她不想逐个回答 Bob 的猜测,只告诉 Bob 这些猜测里面 至少 有 k 个猜测的结果为 true 。

给你二维整数数组 edges ,Bob 的所有猜测和整数 k ,请你返回可能成为树根的 节点数目 。如果没有这样的树,则返回 0。

示例 1:

在这里插入图片描述

输入:edges = [[0,1],[1,2],[1,3],[4,2]], guesses = [[1,3],[0,1],[1,0],[2,4]], k = 3
输出:3
解释:
根为节点 0 ,正确的猜测为 [1,3], [0,1], [2,4]
根为节点 1 ,正确的猜测为 [1,3], [1,0], [2,4]
根为节点 2 ,正确的猜测为 [1,3], [1,0], [2,4]
根为节点 3 ,正确的猜测为 [1,0], [2,4]
根为节点 4 ,正确的猜测为 [1,3], [1,0]
节点 0 ,1 或 2 为根时,可以得到 3 个正确的猜测。
示例 2:
在这里插入图片描述

输入:edges = [[0,1],[1,2],[2,3],[3,4]], guesses = [[1,0],[3,4],[2,1],[3,2]], k = 1
输出:5
解释:
根为节点 0 ,正确的猜测为 [3,4]
根为节点 1 ,正确的猜测为 [1,0], [3,4]
根为节点 2 ,正确的猜测为 [1,0], [2,1], [3,4]
根为节点 3 ,正确的猜测为 [1,0], [2,1], [3,2], [3,4]
根为节点 4 ,正确的猜测为 [1,0], [2,1], [3,2]
任何节点为根,都至少有 1 个正确的猜测。

提示:

edges.length == n - 1
2 <= n <= 1e5
1 <= guesses.length <= 1e5
0 <= ai, bi, uj, vj <= n - 1
ai != bi
uj != vj
edges 表示一棵有效的树。
guesses[j] 是树中的一条边。
guesses 是唯一的。
0 <= k <= guesses.length

菜鸡不会,参考灵神题解,换根DP:

using LL = long long;class Solution {
public:int rootCount(vector<vector<int>>& edges, vector<vector<int>>& guesses,int k) {vector<vector<int>> g(edges.size() + 1);for (auto& e : edges) {int x = e[0], y = e[1];g[x].push_back(y);g[y].push_back(x);}unordered_set<LL> s;for (auto& e : guesses) {s.insert((LL)e[0] << 32 | e[1]);}int ans = 0, cnt0 = 0;function<void(int, int)> dfs = [&](int x, int fa) {for (int y : g[x]) {if (y != fa) {cnt0 += s.count((LL)x << 32 | y);dfs(y, x);}}};dfs(0, -1);function<void(int, int, int)> reroot = [&](int x, int fa, int cnt) {ans += cnt >= k;for (int y : g[x]) {if (y != fa) {reroot(y, x,cnt - s.count((LL)x << 32 | y) +s.count((LL)y << 32 | x));}}};reroot(0, -1, cnt0);return ans;}
};

题解在这里:换根 DP(Python/Java/C++/Go)

2369. 检查数组是否存在有效划分

给你一个下标从 0 开始的整数数组 nums ,你必须将数组划分为一个或多个 连续 子数组。

如果获得的这些子数组中每个都能满足下述条件 之一 ,则可以称其为数组的一种 有效 划分:

子数组 恰 由 2 个相等元素组成,例如,子数组 [2,2] 。
子数组 恰 由 3 个相等元素组成,例如,子数组 [4,4,4] 。
子数组 恰 由 3 个连续递增元素组成,并且相邻元素之间的差值为 1 。例如,子数组 [3,4,5] ,但是子数组 [1,3,5] 不符合要求。
如果数组 至少 存在一种有效划分,返回 true ,否则,返回 false 。

示例 1:

输入:nums = [4,4,4,5,6]
输出:true
解释:数组可以划分成子数组 [4,4] 和 [4,5,6] 。
这是一种有效划分,所以返回 true 。
示例 2:

输入:nums = [1,1,1,2]
输出:false
解释:该数组不存在有效划分。

提示:

2 <= nums.length <= 1e5
1 <= nums[i] <= 1e6

仍然是DP题:

class Solution {
public:bool validPartition(vector<int>& nums) {int n = nums.size();vector<int> f(n + 1);f[0] = true;for (int i = 1; i < n; i++) {if (f[i - 1] && nums[i] == nums[i - 1] ||i > 1 && f[i - 2] &&(nums[i] == nums[i - 1] && nums[i] == nums[i - 2] ||nums[i] == nums[i - 1] + 1 &&nums[i] == nums[i - 2] + 2)) {f[i + 1] = true;}}return f[n];}
};

还是灵神牛orz

2368. 受限条件下可到达节点的数目

现有一棵由 n 个节点组成的无向树,节点编号从 0 到 n - 1 ,共有 n - 1 条边。

给你一个二维整数数组 edges ,长度为 n - 1 ,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间存在一条边。另给你一个整数数组 restricted 表示 受限 节点。

在不访问受限节点的前提下,返回你可以从节点 0 到达的 最多 节点数目。

注意,节点 0 不 会标记为受限节点。

示例 1:

在这里插入图片描述

输入:n = 7, edges = [[0,1],[1,2],[3,1],[4,0],[0,5],[5,6]], restricted = [4,5]
输出:4
解释:上图所示正是这棵树。
在不访问受限节点的前提下,只有节点 [0,1,2,3] 可以从节点 0 到达。
示例 2:

在这里插入图片描述

输入:n = 7, edges = [[0,1],[0,2],[0,5],[0,4],[3,2],[6,5]], restricted = [4,2,1]
输出:3
解释:上图所示正是这棵树。
在不访问受限节点的前提下,只有节点 [0,5,6] 可以从节点 0 到达。

提示:

2 <= n <= 1e5
edges.length == n - 1
edges[i].length == 2
0 <= ai, bi < n
ai != bi
edges 表示一棵有效的树
1 <= restricted.length < n
1 <= restricted[i] < n
restricted 中的所有值 互不相同

树上DFS:

class Solution {vector<vector<int>> g;int dfs(int x, int fa) {int cnt = 1;for (int y : g[x]) {if (y != fa) {cnt += dfs(y, x);}}return cnt;};public:int reachableNodes(int n, vector<vector<int>> &edges, vector<int> &restricted) {unordered_set<int> r(restricted.begin(), restricted.end());g.resize(n);for (auto &e : edges) {int x = e[0], y = e[1];if (!r.contains(x) && !r.contains(y)) {g[x].push_back(y); // 都不受限才连边g[y].push_back(x);}}return dfs(0, -1);}
};

第一次见这种题,看了题解:树上 DFS(Python/Java/C++/Go/JS/Rust)

225. 用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:

输入:
[“MyStack”, “push”, “push”, “top”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]

解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:

1 <= x <= 9
最多调用100 次 push、pop、top 和 empty
每次调用 pop 和 top 都保证栈不为空

进阶:你能否仅用一个队列来实现栈。

数据结构基础:

class MyStack {
public:MyStack() {}void push(int x) {q2.push(x);while (!q1.empty()) {q2.push(q1.front());q1.pop();}swap(q1, q2);}int pop() {int x = q1.front();q1.pop();return x;}int top() { return q1.front(); }bool empty() { return q1.empty(); }private:queue<int> q1;queue<int> q2;
};/*** Your MyStack object will be instantiated and called as such:* MyStack* obj = new MyStack();* obj->push(x);* int param_2 = obj->pop();* int param_3 = obj->top();* bool param_4 = obj->empty();*/

使用一个队列实现栈:

class MyStack {
public:queue<int> q;MyStack() {}void push(int x) {int n = q.size();q.push(x);for (int i = 0; i < n; i++) {q.push(q.front());q.pop();}}int pop() {int r = q.front();q.pop();return r;}int top() {int r = q.front();return r;}bool empty() { return q.empty(); }
};

232. 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:

你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入:
[“MyQueue”, “push”, “push”, “peek”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

提示:

1 <= x <= 9
最多调用 100 次 push、pop、peek 和 empty
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

进阶:

你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

数据结构基础:

class MyQueue {
public:MyQueue() {}void push(int x) { input.push(x); }int pop() {peek();int front = output.top();output.pop();return front;}int peek() {if (output.empty()) {while (!input.empty()) {output.push(input.top());input.pop();}}return output.top();}bool empty() { return input.empty() && output.empty(); }private:std::stack<int> input;std::stack<int> output;
};

1976. 到达目的地的方案数

你在一个城市里,城市由 n 个路口组成,路口编号为 0 到 n - 1 ,某些路口之间有 双向 道路。输入保证你可以从任意路口出发到达其他任意路口,且任意两个路口之间最多有一条路。

给你一个整数 n 和二维整数数组 roads ,其中 roads[i] = [ui, vi, timei] 表示在路口 ui 和 vi 之间有一条需要花费 timei 时间才能通过的道路。你想知道花费 最少时间 从路口 0 出发到达路口 n - 1 的方案数。

请返回花费 最少时间 到达目的地的 路径数目 。由于答案可能很大,将结果对 109 + 7 取余 后返回。

示例 1:

输入:n = 7, roads = [[0,6,7],[0,1,2],[1,2,3],[1,3,3],[6,3,3],[3,5,1],[6,5,1],[2,5,1],[0,4,5],[4,6,2]]
输出:4
解释:从路口 0 出发到路口 6 花费的最少时间是 7 分钟。
四条花费 7 分钟的路径分别为:

  • 0 ➝ 6
  • 0 ➝ 4 ➝ 6
  • 0 ➝ 1 ➝ 2 ➝ 5 ➝ 6
  • 0 ➝ 1 ➝ 3 ➝ 5 ➝ 6
    示例 2:

输入:n = 2, roads = [[1,0,10]]
输出:1
解释:只有一条从路口 0 到路口 1 的路,花费 10 分钟。

提示:

1 <= n <= 200
n - 1 <= roads.length <= n * (n - 1) / 2
roads[i].length == 3
0 <= ui, vi <= n - 1
1 <= timei <= 1e9
ui != vi
任意两个路口之间至多有一条路。
从任意路口出发,你能够到达其他任意路口。

迪杰斯特拉最短路:

const int MOD = 1e9 + 7;
typedef pair<long long, int> PLI;
typedef pair<int, int> PII;class Solution {
public:int countPaths(int n, vector<vector<int>>& roads) {vector<vector<PII>> graph(n);for (auto& road : roads) {int u = road[0], v = road[1], t = road[2];graph[u].emplace_back(v, t);graph[v].emplace_back(u, t);}vector<long long> dist(n, 1e18);vector<int> count(n);dist[0] = 0;count[0] = 1;priority_queue<PLI, vector<PLI>, greater<PLI>> pq;pq.emplace(0, 0);while (!pq.empty()) {auto [d, u] = pq.top();pq.pop();if (d != dist[u])continue;for (auto [v, t] : graph[u]) {if (dist[u] + t < dist[v]) {dist[v] = dist[u] + t;count[v] = count[u];pq.emplace(dist[v], v);} else if (dist[u] + t == dist[v]) {count[v] = (count[v] + count[u]) % MOD;}}}return count[n - 1];}
};

灵神题解也写得非常好,Dijkstra算法同样也是考研408的重点:在计算最短路的同时 DP!

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

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

相关文章

好书推荐丨细说PyTorch深度学习:理论、算法、模型与编程实现

文章目录 写在前面深度学习推荐图书内容简介作者简介 推荐理由粉丝福利写在最后 写在前面 本期博主给大家推荐一本深度学习的全新正版书籍&#xff0c;感兴趣的小伙伴快来看看吧~ 深度学习 深度学习是机器学习的一个分支&#xff0c;它模仿人脑神经网络的工作原理进行复杂的…

蓝桥杯练习系统(算法训练)ALGO-986 藏匿的刺客

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 强大的kAc建立了强大的帝国&#xff0c;但人民深受其学霸及23文化的压迫&#xff0c;于是勇敢的鹏决心反抗。   kAc帝国防…

linux kernel物理内存概述(二)

目录 物理内存数据结构 设备数物理内存描述 物理内存映射 map_kernel map_mem zone数据结构 zone类型 物理内存数据结构 站在处理器角度&#xff0c;管理物理内存的最小单位是页面。使用page数据结构描述&#xff0c;通常默认大小4kB&#xff0c;采用mem_map[]数组来存…

学习java第一天(下载并配置环境+写第一个java程序)

一.安装 1.下载 直接去官网上选择与你电脑符合的版本下载 官网链接Java Archive Downloads - Java SE 8u211 and later &#xff08;拿我的为例 Windows x64版本&#xff09; ​ 2.然后安装好exe&#xff08;要让自己知道在哪&#xff09; 3.配置环境 大佬链接&#xff1…

“每一次的感应,都是对环境的温柔拥抱。”#STM32项目二 《感应开关盖垃圾桶》【上】

“每一次的感应&#xff0c;都是对环境的温柔拥抱。”#STM32项目二 《感应开关盖垃圾桶》【上】 前言预备知识1.定时器介绍11.1软件延时的优缺点1.2定时器工作原理1.3定时器的分类1.4 STM32F103C8T6定时器资源1.5通用定时器介绍 2.定时器介绍22.1定时器计数模式2.2定时器时钟源…

【VTKExamples::PolyData】第四十六期 Reflection

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例Reflection,并解析接口vtkReflectionFilter,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. Reflection …

Docker容器详解

一、概述 1.1 基本概念&#xff1a; Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从Apache2.0协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚…

SpringCloud 各自组件的停更/升级/替换

一、停更不停用 现在 SpringCloud 不再修复 bug&#xff0c;也不再接收合并请求&#xff0c;也不再发布新版本&#xff0c;但是目前还是可以继续使用的。 二、以前的组件 以前 SpringCloud 常用的组件如下图&#xff0c;服务的注册和发现使用 Eureka&#xff0c;服务的负载和调…

深入理解c指针(七)

目录 十、回调函数和qsort函数 1、回调函数 2、简单介绍size_t 数据类型 3、qsort 排序函数 3.1 qsort函数简单举例1&#xff08;升序排序&#xff09; 3.2 qsort函数简单举例2&#xff08;字符串长度排序&#xff09; 3.3 简单讲解 -> 操作符 3.4 常见符号的ASCII…

如何利用会话式AI提升你的工作效率?

会话式AI如何改变我们的生活和工作 在当今时代&#xff0c;内容策略的重要性日渐凸显&#xff0c;良好的内容策略能够与流量及转化率紧密相连&#xff0c;成为企业在内容策略领域不容忽视的营销工具之一。 然而&#xff0c;目前内容同质化现象严重&#xff0c;企业若想在内容营…

iPaas数据传输的方式

一、iPaas平台概述 iPaas&#xff08;Integration Platform as a Service&#xff09;平台&#xff0c;作为一种先进的云计算服务模式&#xff0c;为开发者和企业提供了一种全面且灵活的应用集成解决方案。它构建在PaaS&#xff08;Platform as a Service&#xff09;基础之上…

【C++庖丁解牛】初始化列表 | Static对象 | 友元函数

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1. 再谈构造函数1.1 …

WiFi模块赋能智能手表:拓展功能与提升连接性

随着科技的不断进步&#xff0c;智能手表正逐渐成为现代人生活中不可或缺的智能配饰。其中&#xff0c;WiFi模块的应用为智能手表带来了更多强大的功能和更高的连接性&#xff0c;为用户提供了更为便捷、智能化的使用体验。本文将深入探讨WiFi模块在智能手表中的应用。 远程通信…

RK DVP NVP6158配置 学习

NVP6158简介 NVP6158C是一款4通道通用RX&#xff0c;提供高质量图像的芯片。它接受来自摄像机和其他视频信号的独立4通道通用输入来源。它将4通道通用1M至8M 7.5P视频格式数字化并解码为代表8位ITU-R BT.656/1120 4:2:2格式的数字分量视频&#xff0c;并将单独的BT.601格式与27…

40个Python字符串实例

Python 字符串是 Python 编程语言中最常用的数据类型之一&#xff0c;它可以表示文本或一组字符。Python 中的字符串是不可变的序列&#xff0c;意味着一旦创建&#xff0c;其值就不能被修改。下面是一些关于 Python 字符串的介绍。 概述 创建字符串&#xff1a;可以使用单引…

如何找回删除的文件?5个数据恢复方法

电脑已经成为我们生活和工作不可或缺的一部分。然而随着电脑使用频率的增加&#xff0c;误删文件的情况也时有发生。一旦重要的文件被误删&#xff0c;很多人会感到惊慌失措。实际上只要掌握了一些有效的数据恢复方法&#xff0c;就有可能找回那些被误删的文件。本文将为你介绍…

指针中的回调函数与qsort的深度理解与模拟

今天给大家在更新一下指针类型的知识&#xff0c;这里讲到了一个库函数sqort&#xff0c;以及回调函数的理解。 望喜欢 目录 回调函数 qsort函数 qsort模拟实现 回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数…

Mac清理电脑垃圾工具CleanMyMac X4.15中文免费版下载

嘿&#xff0c;亲爱的Mac用户们&#xff0c;你们是否曾经想象过你的电脑是一座美丽的城市&#xff0c;而垃圾文件则是那些不速之客&#xff0c;悄悄堆积&#xff0c;影响着城市的整体美观。今天&#xff0c;我们就来聊聊Mac为什么会产生垃圾文件&#xff0c;这些垃圾文件会对你…

【科研基础】插图摘录

FedSL: Federated Split Learning for Collaborative Healthcare Analytics on Resource-Constrained Wearable IoMT Devices Blockchain-Based Trustworthy and Efficient Hierarchical Federated Learning for UAV-Enabled IoT Networks

机械五要素手持气象站的应用

TH-SQ5在数字化和智能化的时代背景下&#xff0c;气象监测技术正日益成为众多行业不可或缺的利器。其中&#xff0c;机械五要素手持气象站以其便携性、实时性和多功能性受到了广泛关注。下面讲解一下手持气象站是什么以及应用&#xff1a; 一、机械五要素手持气象站概述 机械五…