【leetcode练习·二叉树】用「遍历」思维解题 III

本文参考labuladong算法笔记[【强化练习】用「遍历」思维解题 III | labuladong 的算法笔记]

437. 路径总和 III | 力扣 | LeetCode |

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例 1:

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。

示例 2:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:3

提示:

  • 二叉树的节点个数的范围是 [0,1000]
  • -109 <= Node.val <= 109
  • -1000 <= targetSum <= 1000

这题及要求你准确理解二叉树的前序后序遍历,还要熟悉前缀和技巧,把前缀和技巧用到二叉树上。

你可以先看前文 前缀和技巧,然后做一下 560. 和为K的子数组,应该能够理解这道题的思路了。

你把二叉树看做是数组,利用前后序遍历来维护前缀和,看下图就能理解解法中几个关键变量的关系了:

 

class Solution:# 记录前缀和# 定义:从二叉树的根节点开始,路径和为 pathSum 的路径有 preSumCount.get(pathSum) 个def __init__(self):self.preSumCount = {}self.path_sum = 0self.target_sum = 0self.res = 0def pathSum(self, root: TreeNode, targetSum: int) -> int:if root is None:return 0self.path_sum = 0self.target_sum = targetSumself.preSumCount[0] = 1self.traverse(root)return self.resdef traverse(self, root: TreeNode):if root is None:return# 前序遍历位置self.path_sum += root.val# 从二叉树的根节点开始,路径和为 pathSum - targetSum 的路径条数# 就是路径和为 targetSum 的路径条数self.res += self.preSumCount.get(self.path_sum - self.target_sum, 0)# 记录从二叉树的根节点开始,路径和为 pathSum 的路径条数self.preSumCount[self.path_sum] = self.preSumCount.get(self.path_sum, 0) + 1self.traverse(root.left)self.traverse(root.right)# 后序遍历位置self.preSumCount[self.path_sum] = self.preSumCount.get(self.path_sum) - 1self.path_sum -= root.val

513. 找树左下角的值 | 力扣 | LeetCode |

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

示例 1:

输入: root = [2,1,3]
输出: 1

示例 2:

输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7

提示:

  • 二叉树的节点个数的范围是 [1,104]
  • -231 <= Node.val <= 231 - 1

二叉树递归框架代码是先递归左子树,后递归右子树,所以到最大深度时第一次遇到的节点就是左下角的节点。

class Solution:def __init__(self):# 记录二叉树的最大深度self.maxDepth = 0# 记录 traverse 递归遍历到的深度self.depth = 0self.res = Nonedef findBottomLeftValue(self, root: TreeNode) -> int:self.traverse(root)return self.res.valdef traverse(self, root: TreeNode):if root is None:return# 前序遍历位置self.depth += 1if self.depth > self.maxDepth:# 到最大深度时第一次遇到的节点就是左下角的节点self.maxDepth = self.depthself.res = rootself.traverse(root.left)self.traverse(root.right)# 后序遍历位置self.depth -= 1

1261. 在受污染的二叉树中查找元素 | 力扣 | LeetCode |

给出一个满足下述规则的二叉树:

  1. root.val == 0
  2. 如果 treeNode.val == x 且 treeNode.left != null,那么 treeNode.left.val == 2 * x + 1
  3. 如果 treeNode.val == x 且 treeNode.right != null,那么 treeNode.right.val == 2 * x + 2

现在这个二叉树受到「污染」,所有的 treeNode.val 都变成了 -1

请你先还原二叉树,然后实现 FindElements 类:

  • FindElements(TreeNode* root) 用受污染的二叉树初始化对象,你需要先把它还原。
  • bool find(int target) 判断目标值 target 是否存在于还原后的二叉树中并返回结果。

示例 1:

输入:
["FindElements","find","find"]
[[[-1,null,-1]],[1],[2]]
输出:
[null,false,true]
解释:
FindElements findElements = new FindElements([-1,null,-1]); 
findElements.find(1); // return False 
findElements.find(2); // return True 

示例 2:

输入:
["FindElements","find","find","find"]
[[[-1,-1,-1,-1,-1]],[1],[3],[5]]
输出:
[null,true,true,false]
解释:
FindElements findElements = new FindElements([-1,-1,-1,-1,-1]);
findElements.find(1); // return True
findElements.find(3); // return True
findElements.find(5); // return False

示例 3:

输入:
["FindElements","find","find","find","find"]
[[[-1,null,-1,-1,null,-1]],[2],[3],[4],[5]]
输出:
[null,true,false,false,true]
解释:
FindElements findElements = new FindElements([-1,null,-1,-1,null,-1]);
findElements.find(2); // return True
findElements.find(3); // return False
findElements.find(4); // return False
findElements.find(5); // return True

提示:

  • TreeNode.val == -1
  • 二叉树的高度不超过 20
  • 节点的总数在 [1, 10^4] 之间
  • 调用 find() 的总次数在 [1, 10^4] 之间
  • 0 <= target <= 10^6

还原二叉树的时候只需要遍历所有节点,通过函数参数传递每个节点的值;由于节点的个数规模不算大,所以可以直接用一个 HashSet 缓存所有节点值,实现 find 函数的功能。

当然,题目给的这种二叉树节点的取值规律非常像用数组存储完全二叉树的场景,所以你应该可以通过 target 推算出来它在第几层的什么位置,不过我这里就不实现了,类似的题目你可以参考 1104. 二叉树寻路 和 662. 二叉树最大宽度。

class FindElements:# 帮助 find 函数快速判断def __init__(self, root):# 还原二叉树中的值self.values = set()self.traverse(root, 0)# 二叉树遍历函数def traverse(self, root, val):if root is None:returnroot.val = valself.values.add(val)self.traverse(root.left, 2 * val + 1)self.traverse(root.right, 2 * val + 2)def find(self, target):return target in self.values

386. 字典序排数 | 力扣 | LeetCode |

给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。

你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。

示例 1:

输入:n = 13
输出:[1,10,11,12,13,2,3,4,5,6,7,8,9]

示例 2:

输入:n = 2
输出:[1,2]

提示:

  • 1 <= n <= 5 * 104

这个题还挺有意思,要不是它把这道题放在 DFS 的题目分类里面,可能还不太好发现这是一个 DFS 的题目。

它的递归树大概是这样生长的:

首先看 1 这个节点,1 可以生出二位数 10, 11, 12...

其中 10 又可以生出 100, 101, 102...,11 又可以生出 110, 111, 112...

这棵多叉树是不是就出来了?每个节点最多可以生出 10 个节点,这就是一个十叉树。

class Solution:def __init__(self):self.res = []def lexicalOrder(self, n: int) -> List[int]:# 总共有 9 棵多叉树,从 1 开始for i in range(1, 10):self.traverse(i, n)return self.res# 多叉树遍历框架,前序位置收集所有小于 n 的节点def traverse(self, root: int, n: int) -> None:if root > n:returnself.res.append(root)for child in range(root * 10, root * 10 + 10):if child > n:breakself.traverse(child, n)

1104. 二叉树寻路 | 力扣 | LeetCode |

在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。

如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;

而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。

给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。

示例 1:

输入:label = 14
输出:[1,3,4,14]

示例 2:

输入:label = 26
输出:[1,2,6,10,26]

提示:

  • 1 <= label <= 10^6

先假设全都是从左到右排列,没有之字形排列的这个条件:

 

如果我想求到达某一个 label 节点的路径,那么我一直对 label 除以 2 就行了(忽略余数)。

你比如我想求到达 13 的路径,就是 13, 6, 3, 1,然后反转一下就行了。大致的代码逻辑如下:

ArrayList<Integer> path = new ArrayList<>();
while (label >= 1) {path.add(label);label = label / 2;
}
// 反转成从根节点到目标节点的路径
Collections.reverse(path);

现在虽然是之字形排列,但稍加修改就可以适应这个变化:

13 的父节点不是 6 了,而是 7 - (6 - 4) = 5。

这个 7 和 4 是哪里来的?就是 6 这一行的最小节点值和最大节点值,而对于完全二叉树,每一行的最大最小值可以通过计算 2 的指数算出来的。

import mathclass Solution:def pathInZigZagTree(self, label: int) -> List[int]:res = []# 对于常规杨辉三角的二叉树,某一节点自身连续除以2,所得值即为该节点到根节点的路径while label > 0:res.append(label)label //= 2# 反转成从根节点到目标节点的路径res.reverse()# 对于“之”字形排列的杨辉三角,label在奇数行和偶数行的效果不一样,需要加以区分label_id = len(res) - 1# 判断label在奇数行还是偶数行is_odd = label_id % 2return self.get_new_val(is_odd, res)# 画个图就容易理解奇数行和偶数行各自的情况了def get_new_val(self, is_odd, res):for id, val in enumerate(res):if id % 2 == 1 - is_odd:max_val = int(math.pow(2, id+1)) - 1min_val = int(math.pow(2, id))# 由于该行可能被翻转,则需要找到翻转后对应的值res[id] = min_val + max_val - valreturn res

1145. 二叉树着色游戏 | 力扣 | LeetCode |

有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中,给出二叉树的根节点 root,树上总共有 n 个节点,且 n 为奇数,其中每个节点上的值从 1 到 n 各不相同。

最开始时:

  • 「一号」玩家从 [1, n] 中取一个值 x1 <= x <= n);
  • 「二号」玩家也从 [1, n] 中取一个值 y1 <= y <= n)且 y != x

「一号」玩家给值为 x 的节点染上红色,而「二号」玩家给值为 y 的节点染上蓝色。

之后两位玩家轮流进行操作,「一号」玩家先手。每一回合,玩家选择一个被他染过色的节点,将所选节点一个 未着色 的邻节点(即左右子节点、或父节点)进行染色(「一号」玩家染红色,「二号」玩家染蓝色)。

如果(且仅在此种情况下)当前玩家无法找到这样的节点来染色时,其回合就会被跳过。

若两个玩家都没有可以染色的节点时,游戏结束。着色节点最多的那位玩家获得胜利 ✌️。

现在,假设你是「二号」玩家,根据所给出的输入,假如存在一个 y 值可以确保你赢得这场游戏,则返回 true ;若无法获胜,就请返回 false 。

 

示例 1 :

输入:root = [1,2,3,4,5,6,7,8,9,10,11], n = 11, x = 3
输出:true
解释:第二个玩家可以选择值为 2 的节点。

示例 2 :

输入:root = [1,2,3], n = 3, x = 1
输出:false

提示:

  • 树中节点数目为 n
  • 1 <= x <= n <= 100
  • n 是奇数
  • 1 <= Node.val <= n
  • 树中所有值 互不相同

基本思路

这道题的关键是要观察规律,根据游戏规则,对方先选一个节点之后,你的最优策略就是紧贴着对方的那个节点选择,也就是说你应该选择节点 x 的左右子节点或者父节点。

做出以上三种选择,你可以占据二叉树的不同部分,如下图:

 你如果想赢,必须占据超过 n / 2 的节点,也就是说,如果这三个蓝色区域中节点数最多的那个区域中的节点个数大于 n / 2,你能赢,否则你就输。

所以本题转化为计算二叉树节点个数的简单问题。

class Solution:def btreeGameWinningMove(self, root: TreeNode, n: int, x: int) -> bool:node = self.find(root, x)left_count = self.count(node.left)right_count = self.count(node.right)other_count = n - 1 - left_count - right_countreturn max(left_count, max(right_count, other_count)) > n // 2# 定义:在以 root 为根的二叉树中搜索值为 x 的节点并返回def find(self, root: TreeNode, x: int) -> TreeNode:if root is None:return Noneif root.val == x:return root# 去左子树找left = self.find(root.left, x)if left is not None:return left# 左子树找不到的话去右子树找return self.find(root.right, x)# 定义:计算以 root 为根的二叉树的节点总数def count(self, root: TreeNode) -> int:if root is None:return 0return 1 + self.count(root.left) + self.count(root.right)

1612. 检查两棵二叉表达式树是否等价 | 力扣 | LeetCode |

二叉表达式树是一种表达算术表达式的二叉树。二叉表达式树中的每一个节点都有零个或两个子节点。 叶节点(有 0 个子节点的节点)表示操作数,非叶节点(有 2 个子节点的节点)表示运算符。在本题中,我们只考虑 '+' 运算符(即加法)。

给定两棵二叉表达式树的根节点 root1 和 root2 。如果两棵二叉表达式树等价,返回 true ,否则返回 false 。

当两棵二叉搜索树中的变量取任意值,分别求得的值都相等时,我们称这两棵二叉表达式树是等价的。

示例 1:

输入: root1 = [x], root2 = [x]
输出: true

示例 2:

输入:root1 = [+,a,+,null,null,b,c], root2 = [+,+,a,b,c]
输出:true
解释:a + (b + c) == (b + c) + a

示例 3:

输入: root1 = [+,a,+,null,null,b,c], root2 = [+,+,a,b,d]
输出: false
解释: a + (b + c) != (b + d) + a

提示:

  • 两棵树中的节点个数相等,且节点个数为范围 [1, 4999] 内的奇数。
  • Node.val 是 '+' 或小写英文字母。
  • 给定的树保证是有效的二叉表达式树。

进阶:当你的答案需同时支持 '-' 运算符(减法)时,你该如何修改你的答案

题目说算式中只有加号,所以判断两个算式是否相同,只需要分别遍历两棵二叉树,判断两棵二叉树中的未知数数量是否相同即可。

有了这个思路就很容易写出解法了,我们可以用一个小技巧,用 count 数组当做计数器,对第一棵树上的元素 +1,对第二棵树上的元素 -1,这样一来,只要最终 count 数组中全是 0 就说明两棵树上的未知数数量相同。

class Solution:def checkEquivalence(self, root1: 'Node', root2: 'Node') -> bool:# 给 root1 的未知数计数self.traverse(root1, 1)# 给 root2 的未知数计数self.traverse(root2, -1)# 如果等价,未知数的数量应该相同for f in self.count:if f != 0:return Falsereturn True# 记录未知数def __init__(self):self.count = [0] * 26# 二叉树遍历函数def traverse(self, root: 'Node', delta: int):if root is None:return# 改变未知数的个数if 'a' <= root.val <= 'z':self.count[ord(root.val) - ord('a')] += deltaself.traverse(root.left, delta)self.traverse(root.right, delta)

 

572. 另一棵树的子树 | 力扣 | LeetCode |

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

示例 1:

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true

示例 2:

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false

提示:

  • root 树上的节点数量范围是 [1, 2000]
  • subRoot 树上的节点数量范围是 [1, 1000]
  • -104 <= root.val <= 104
  • -104 <= subRoot.val <= 104

遍历以 root 为根的这棵二叉树的所有节点,用 100. 相同的树 中的 isSame 函数判断以该节点为根的子树是否和以 subRoot 为根的那棵树相同。

class Solution:def isSubtree(self, root: TreeNode, subRoot: TreeNode) -> bool:if root is None:return subRoot is None# 判断以 root 为根的二叉树是否和 subRoot 相同if self.isSameTree(root, subRoot):return True# 去左右子树中判断是否有和 subRoot 相同的子树# 妙就妙在中间这个 or !!! 因为它只要左子树或右子树其一包含即可return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:# 判断一对节点是否相同,经典判断两棵二叉树是否相等的代码if p is None and q is None:return Trueif p is None or q is None:return Falseif p.val != q.val:return False# 判断其他节点是否相同return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)

1367. 二叉树中的链表 | 力扣 | LeetCode |

给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表。

如果在二叉树中,存在一条一直向下的路径,且每个点的数值恰好一一对应以 head 为首的链表中每个节点的值,那么请你返回 True ,否则返回 False 。

一直向下的路径的意思是:从树中某个节点开始,一直连续向下的路径。

示例 1:

输入:head = [4,2,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true
解释:树中蓝色的节点构成了与链表对应的子路径。

示例 2:

输入:head = [1,4,2,6], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true

示例 3:

输入:head = [1,4,2,6,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:false
解释:二叉树中不存在一一对应链表的路径。

提示:

  • 二叉树和链表中的每个节点的值都满足 1 <= node.val <= 100 。
  • 链表包含的节点数目在 1 到 100 之间。
  • 二叉树包含的节点数目在 1 到 2500 之间。

本质上,isSubPath 就是在遍历二叉树的所有节点,对每个节点用 check 函数判断是否能够将链表嵌进去。

class Solution:def isSubPath(self, head: ListNode, root: TreeNode) -> bool:# base caseif head is None:return Trueif root is None:return False# 当找到一个二叉树节点的值等于链表头结点时if head.val == root.val:# 判断是否能把链表嵌进去if self.check(head, root):return True# 继续去遍历其他节点尝试嵌入链表,妙就妙在这个 or !!!return self.isSubPath(head, root.left) or self.isSubPath(head, root.right)# 检查是否能够将链表嵌入二叉树def check(self, head: ListNode, root: TreeNode) -> bool:if head is None:return Trueif root is None:return Falseif head.val == root.val:# 在子树上嵌入子链表return self.check(head.next, root.left) or self.check(head.next, root.right)return False

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

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

相关文章

c语言基础程序——经典100道实例(二)

前面 52 题可以看下 《c语言基础程序——经典100道实例。》 c语言基础程序——经典100道实例 053&#xff0c;按位异或 ^054&#xff0c;取数右端4~7位055&#xff0c;按位取反~056&#xff0c;画圆形057&#xff0c;画直线058&#xff0c;画矩形059&#xff0c;画椭圆060&…

Git上传命令汇总

进入企业&#xff0c;每日需要上传执行用例记录到gitlab平台上&#xff0c;本文记录了常用git上传命令&#xff0c; 并用github演示。 1、本地建立分支&#xff0c;克隆远程仓库 在gitlab中&#xff0c;每个人需要创建自己的分支&#xff0c;一般以自己的名字命名&#xff0c;…

FineReport 页面设置

点击菜单栏中的「模板>页面设置」&#xff0c;弹出页面设置对话框&#xff0c;就可以对当前 sheet 进行页面设置&#xff0c;一个报表的每个 sheet 页面设置可以不同&#xff1a; 1 方向 指纸张方向&#xff0c;通常与打印结合使用。A4 纸横向预览效果和纵向预览效果 2、…

HCIP-HarmonyOS Application Developer 习题(十四)

&#xff08;多选&#xff09;1、HarmonyOs为应用提供丰富的Al(Artificial Intelligence)能力&#xff0c;支持开箱即用。下列哪些是它拥有的AI能力? A、通用文字识别 B、词性标注 C、实体识别 D、语音播报 答案&#xff1a;ABCD 分析&#xff1a; AI能力简介二维码生成根据开…

为什么软件维护成本比软件的开发成本高?

很多项目的软件维护成本比软件的开发成本高出很多 一、需求变更频繁 业务需求变化 随着市场环境的变化和业务的发展&#xff0c;客户的需求可能会不断调整和改变。例如&#xff0c;企业的业务模式发生调整&#xff0c;需要软件系统增加新的功能模块或对现有功能进行重大修改…

为什么一条Java命令,JVM就可以执行Java程序了(串联JVM面试知识点)

文章目录 前言从面试题说起JVM做了哪些事&#xff1f;“翻译”的工作不仅仅“翻译” JVM 各部件如何协同工作&#xff1f;类加载器先工作执行引擎开始工作执行引擎工作模式Main方法什么时候被执行&#xff1f; 运行时数据区域开始工作线程私有的空间大名鼎鼎的堆内存 就这么一直…

FineReport 条件属性

条件属性主要指&#xff1a;给报表的属性添加条件&#xff0c;当满足该条件时&#xff0c;对属性的属性值进行修改&#xff0c;从而达到改变报表样式的目的。 条件属性共有 12 种&#xff0c;分别是&#xff1a;颜色、字体、超级链接、形态、缩进、行高、分页、列宽、背景、边框…

Oracle 使用位图索引 Cost降低200倍! 探讨位图索引的利与弊

一.简介 位图索引&#xff08;Bitmap Index&#xff09; 是 Oracle 数据库中一种特殊类型的索引&#xff0c;适用于低基数&#xff08;Low Cardinality&#xff09;列&#xff0c;即那些列中可选值相对较少的情况下使用。它与常规的 B-tree 索引不同&#xff0c;位图索引通过位…

Columns Page “列”页面

“列”页提供了列管理工具&#xff0c;其中包括用于添加和删除列的按钮、显示绑定数据源中字段名称的列表框以及网格列、提供对所选列属性的访问的属性网格。 Columns 页面提供 Column properties &#xff08;列属性&#xff09;、Column options &#xff08;列选项&#xff…

【Git】远程操作-标签管理-多人协作

远程操作 分布式版本控制系统 概念理解 Git就像正在看的一本书。每当看完一章&#xff0c;可以将其保存起来&#xff0c;如果后面想修改或者查看以前自己看到哪里&#xff0c;随时可以翻看。Git就是帮助记录这些修改的工具&#xff0c;主要负责记录每次改动&#xff0c;就类似…

AnaTraf | 网络质量分析与DNS响应时间

http://www.anatraf.com 在当今的数字化时代&#xff0c;网络是任何企业正常运转的核心。而网络的质量直接影响着业务的连续性和用户体验。当网络性能不佳时&#xff0c;可能会导致网站加载缓慢、应用响应滞后&#xff0c;甚至影响企业的生产力。特别是在互联网世界中&#xf…

第三季度中国游戏市场收入创历史新高;京东物流与淘宝天猫达成合作;YouTube 上线“用相机拍摄”标签....|网易数智日报

第三季度中国游戏市场收入917.66亿&#xff0c;创历史新高 中国音数协游戏工委今日发布了最新的 2024 年第三季度中国游戏产业季度报告。 数据显示&#xff0c;2024 年第三季度中国游戏市场收入 917.66 亿元&#xff0c;环比增长 22.96%&#xff0c;同比增长 8.95%。 中国音…

【H2O2|全栈】JS入门知识(五)

目录 JS 前言 准备工作 数组API&#xff08;一&#xff09; API概念 数组常见API&#xff08;一&#xff09; arguments 作用域 概念 全局作用域 局部作用域 块级作用域 变量的作用域 作用域链 案例 预解析 概念 变量预解析 函数预解析 案例 对象 概念 …

【RTT-Studio】详细使用教程十七:FreeModbus通信--LCD

文章目录 一、简介二、Modbus通信三、LCD通信四、配置FreeModbus通信协议四、完整代码五、测试验证 一、简介 Modbus协议是一种用于工业控制的网络通讯协议&#xff0c;可以片面的理解为&#xff0c;Modbus协议一种机器与机器之间进行数据、信息传递的一种格式规范。   Modbu…

PostgreSQL的学习心得和知识总结(一百五十五)|[performance]优化期间将 WHERE 子句中的 IN VALUES 替换为 ANY

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

《MYSQL实战45讲 》 优化器如何选择索引?

SHOW VARIABLES LIKE long_query_time; set long_query_time0 优化器如何选择索引&#xff1f; 1.扫描的行数 估计出各个索引大致的要扫描的行数&#xff0c;行数越少&#xff0c;效率越高。 索引的基数也叫区分度&#xff0c;就是这个索引所在的字段上不同的值又多少个。优…

MySQL【知识改变命运】06

前言&#xff1a;在05这节数据结构里面&#xff0c;我们知道select * from 这个操作很危险&#xff0c;如果数据库很大&#xff0c;会把服务器资源耗尽&#xff0c;接下来提到的查询可以有效的限制返回记录 1&#xff1a;分页查询 分页查询可以有效控制一次查询出来的结果集的…

数据结构与集合源码

目录 一、数据结构 1.1 数据结构概念 1.2 研究对象 1.3 常见存储结构 1.3.1 数组 1.3.2 链表 1.单向链表 2.双向链表 1.3.3 二叉树 1.3.4 栈&#xff08;FILO&#xff0c;先进后出&#xff09; 1.3.5 队列&#xff08;FIFO&#xff0c;先进先出&#xff09; 二、集合…

基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet模型【pytorch框架+python源码】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示&#xff1a; 基于卷积神经网络的蔬菜识别系统&#xff0c;resnet50&#xff0c;mobilenet【pytorch框架&#xff0c;python&#xff0c;tkinter】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神…

Java设计模式梳理:行为型模式(策略,观察者等)

行为型模式 行为型模式关注的是各个类之间的相互作用&#xff0c;将职责划分清楚&#xff0c;使得我们的代码更加地清晰。 策略模式 策略模式太常用了&#xff0c;所以把它放到最前面进行介绍。它比较简单&#xff0c;我就不废话&#xff0c;直接用代码说事吧。 下面设计的…