【Leetcode】top 100 二叉树

基础知识补充

完全二叉树:顺序存储(数组)

        非根节点的父节点序号floor((i-1)/2)

        序号i的左孩子节点序号2*i+1  右孩子节点序号2*i+2

一般二叉树:链式存储

        结构:left指针指向左子节点,right指针指向右子节点,data存储数据项;

class TreeNode(object):        def __init__(self, data, left=None, right=None):        self.data = data            self.left = left            self.right= right           

平衡二叉树:左子树和右子树的高度之差的绝对值不超过1,且左子树和右子树也是平衡二叉树;

二叉搜索树:左子树上所有节点的值都小于根节点的值,右子树上所有节点的值都大于根节点的值,且左子树和右子树也是二叉搜索树

基础操作补充

1. 二叉树的插入

        先判断父节点是否存在,再判断左子节点是否存在;构建右子节点后需要弹出父节点;

class BinTree():def _init__(self):self.root = None self.ls =[]def add(self,data):node = TreeNode(data)if self.root == None:self.root = nodeself.ls.append(self.root)else:rootNode = self.ls[0]if rootNode.left == None:rootNode.left = nodeself.ls.append(rootNode.left)elif rootNode.right == None:rootNode.right = nodeself.ls.append(rootNode.right)self.ls.pop(0)          #弹出子树已满的节点

2. 二叉树的遍历

        前序遍历(深度优先)当前节点-当前节点的左子树-当前节点的右子树    递归或栈实现

        中序遍历(深度优先)当前节点的左子树-当前节点-当前节点的右子树    递归或栈实现

        后序遍历(深度优先)当前节点的左子树-当前节点的右子树-当前节点    递归或栈实现

        层序遍历(广度优先)各层级中从左到右的遍历    队列实现

已知两种二叉树遍历序列(其中需要包括中序遍历)可以唯一确定一棵二叉树;

#前序遍历的递归实现    def preOrderTraversal(self,root):  if root == None: returnprint(root.data)self.preOrderTraversal(root.left)self.preOrderTraversal(root.right)#前序遍历的栈实现def preOrderStack(self,root):     if root == None:returnstack =[]   #存放节点result =[]  #存放节点值node = rootwhile node or stack:while node:              result.append(node.data)stack.append(node)node = node.leftnode = stack.pop()node = node.rightprint(result)#中序遍历的递归实现def inOrderTraversal(self,root):  if root == None: returnself.preOrderTraversal(root.left)print(root.data)self.preOrderTraversal(root.right)#中序遍历的栈实现def inOrderStack(self,root):     if root == None:returnstack =[]   #存放节点result =[]  #存放节点值node = rootwhile node or stack:while node:              stack.append(node)node = node.leftnode = stack.pop()result.append(node.data)node = node.rightprint(result)#后序遍历的递归实现def postOrderTraversal(self,root):  if root == None: returnself.preOrderTraversal(root.left)self.preOrderTraversal(root.right)print(root.data)#后序遍历的栈实现def inOrderStack(self,root):     if root == None:returnstack =[]   #存放节点result =[]  #存放节点值seq = []node = rootwhile node or stack:           #左-右-根视为根-右-左(前序的左右互换)的逆序while node:     seq.append(node.data)         stack.append(node)node = node.right      #内外层左右互换node = stack.pop()node = node.leftwhile seq:result.append(seq.pop())   #逆序print(result)#层序遍历的队列实现def levelOrder(seLf, root):       if root == None:returnqueue =[]result =[]node = rootqueue.append(node)while queue:node = queue.pop(0)result.append(node.data)if node.left != None:queue.append(node.left)if node.right != None:queue.append(node.right)print(result)
题目
94 二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

方法一:递归实现

方法二:栈实现

class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""if root == None: returnstack = []result = []node = rootwhile node or stack:while node:stack.append(node)node = node.leftnode = stack.pop()result.append(node.val)node = node.rightreturn result

方法三颜色标记法:给每个节点一个访问状态,未访问为白,已访问为黑;

中序出栈顺序:左-中-右      对应的入栈顺序:右-中-左        栈:先进后出

class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""white, black = 0, 1result = []stack = [(white, root)]while stack:                         color, node = stack.pop()if node is None:continueif color == white:stack.append((white, node.right))stack.append((black, node))stack.append((white, node.left))      # 适用于前中后序遍历,改变这里位置即可else:result.append(node.val)return result

方法四:莫里斯遍历 

思路:如果左节点不为空,就将当前节点和右子树全部挂在左子树的最右子树下;

           如果左节点为空,打印节点,并向右遍历;

class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res = []pre = Nonewhile root:# 如果左节点不为空,就将当前节点连带右子树全部挂到左节点的最右子树下面if root.left:pre = root.leftwhile pre.right:pre = pre.rightpre.right = root          tmp = root             root = root.left       # 切换到左子树的父节点tmp.left = None        # 取消当前节点到左子树的链接# 左子树为空,则打印这个节点,并向右边遍历	else:res.append(root.val)root = root.rightreturn res
 104 二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。

方法一:二叉树最大深度 = max(左子树高度, 右子树高度)+1

class Solution(object):def maxDepth(self, root):""":type root: TreeNode:rtype: int"""if root is None: return 0 else: left_height = self.maxDepth(root.left) right_height = self.maxDepth(root.right) return max(left_height, right_height) + 1 

方法二:用临时队列维护每层节点,一层结束后将深度+1

class Solution:def maxDepth(self, root):if not root: return 0queue, res = [root], 0while queue:tmp = []for node in queue:if node.left: tmp.append(node.left)if node.right: tmp.append(node.right)queue = tmpres += 1return res
 226 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

方法一:用栈做中序遍历:

class Solution(object):def invertTree(self, root):""":type root: TreeNode:rtype: TreeNode"""stack = []node = rootwhile node or stack:while node:stack.append(node)node = node.leftnode = stack.pop()node.left, node.right = node.right, node.leftnode = node.leftreturn root

方法二:用队列做层级遍历

class Solution(object):def invertTree(self, root):""":type root: TreeNode:rtype: TreeNode"""if root is None:returnqueue = [root]while queue:tmp = queue.pop(0)tmp.left,tmp.right = tmp.right,tmp.leftif tmp.left:queue.append(tmp.left)if tmp.right:queue.append(tmp.right)return root

 方法三:递归实现

class Solution(object):def invertTree(self, root):""":type root: TreeNode:rtype: TreeNode"""if root is None: returnroot.left,root.right = root.right,root.leftself.invertTree(root.left)self.invertTree(root.right)		return root
101 对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

 方法一:用队列做层级遍历,判断每层节点是否对称

class Solution(object):def invertTree(self, root):""":type root: TreeNode:rtype: TreeNode"""quece = [root]while quece:tmp = []val = []for node in quece:if node.left:tmp.append(node.left)val.append(node.left.val)else:val.append(101)                # 101是节点值范围之外的数if node.right:tmp.append(node.right)val.append(node.right.val)else:val.append(101)if val != val[::-1]:return False        # 耗时quece = tmpreturn True # 不用滚动队列的话就一次性考虑两个节点,并在放置时将需要比较的节点相邻放置
class Solution(object):def isSymmetric(self, root):""":type root: TreeNode:rtype: bool"""if not root or not (root.left or root.right):return True	queue = [root.left,root.right]while queue:left = queue.pop(0)      right = queue.pop(0)if not (left or right):  # 两个节点都为空continueif not (left and right): # 两个节点中有一个为空return Falseif left.val!=right.val:  # 两个节点的值不相等return Falsequeue.append(left.left)queue.append(right.right)queue.append(left.right)queue.append(right.left)return True

方法二:递归实现

class Solution(object):def isSymmetric(self, root):""":type root: TreeNode:rtype: bool"""if not root: return Truedef dfs(left,right):if not (left or right):   # 两个节点都为空return Trueif not (left and right):  # 两个节点中有一个为空return Falseif left.val!=right.val:   # 两个节点的值不相等return Falsereturn dfs(left.left,right.right) and dfs(left.right,right.left)return dfs(root.left,root.right)
 543 二叉树的直径

给你一棵二叉树的根节点,返回该树的 直径 。二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。两节点之间路径的 长度 由它们之间边数表示。

分析:直径 = 左子树到父节点的最长路径 + 右子树到父节点的最长路径

           左/右子树到父节点的最长路径 = 左/右子树深度

           子树深度不用重复计算:height = max(左子树深度, 右子树深度)+1

方法一:使用全局变量

class Solution(object):def diameterOfBinaryTree(self, root):""":type root: TreeNode:rtype: int"""global maxx maxx = 0def depth(root):if root is None:return 0left = depth(root.left)right = depth(root.right)global maxxmaxx = max(maxx, left+right)return max(left, right)+1depth(root)return maxx

方法二:不使用全局变量

class Solution(object):def diameterOfBinaryTree(self, root):""":type root: TreeNode:rtype: int"""depth, length = self.depth(root)return lengthdef depth(self, root):if root is None:return (0, 0)left_depth, left_length = self.depth(root.left)right_depth, right_length = self.depth(root.right)depth = max(left_depth, right_depth) + 1length = max(left_length, right_length, left_depth + right_depth)return depth, length
102 层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

方法一:两个数组实现

class Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if root is None:return []quece, result = [root], []while quece:                            tmp_res, tmp_que = [], [] while quece:node = quece.pop(0)tmp_res.append(node.val)if node.left:tmp_que.append(node.left)if node.right:tmp_que.append(node.right)result.append(tmp_res)quece = tmp_que                                 return result

方法二:一个数组实现,用变量确定每层需要处理的子节点数即可正常插入数组;

class Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if root is None:return []quece, result = [root], []while quece:     length = len(quece)                       tmp_res = [] for i in range(length):node = quece.pop(0)tmp_res.append(node.val)if node.left:quece.append(node.left)if node.right:quece.append(node.right)result.append(tmp_res)                                return result
108 将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵平衡二叉搜索树。

针对平衡,同时添加左子树和右子树;针对搜索,将数组确定父节点后进行二分;

递归实现

class Solution(object):def sortedArrayToBST(self, nums):""":type nums: List[int]:rtype: TreeNode"""def balanceTree(left, right):if left > right: return Nonemid = (left+right)//2root = TreeNode(nums[mid])root.left = balanceTree(left, mid-1)root.right = balanceTree(mid+1, right)left, right = 0, len(nums)-1return balanceTree(left, right)
98 验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

方法一:验证:左子节点值<父节点值<右子节点值   不够准确

在验证10的右子树时,首先所有值要大于10,即需要记录左右子树的不同边界值(左子树-上界  右子树-下界)

对于节点6来说,先在右子树确定下界为10,再在左子树确定上界为15,而6不属于这个区间;

class Solution(object):def isValidBST(self, root):""":type root: TreeNode:rtype: bool"""def isBST(node, low, up):if node is None:return Trueif node.val<=low or node.val>=up: return Falsereturn isBST(node.left,low,node.val) and isBST(node.right,node.val,up)return isBST(root, -2**31-1, 2**31)   # 题目范围的边界值

方法二:利用"二叉搜索树的中序遍历一定升序排列"性质;

              在构建中序遍历数组的同时可以进行升序比较;

230 二叉搜索树中第K小的元素

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

利用"二叉搜索树的中序遍历一定升序排列"性质;构建中序遍历数组后直接取出第k个值即可;不构建中序遍历数组的话也可以选择对k处理(在需要插入值的位置将k减一,k归零时对应输出);

class Solution(object):def kthSmallest(self, root, k):""":type root: TreeNode:type k: int:rtype: int"""stack = []result = []while root or stack:while root:stack.append(root)root = root.leftroot = stack.pop()result.append(root.val)root = root.rightreturn result[k-1]class Solution:def kthSmallest(self, root, k):stack = []while root or stack:while root:stack.append(root)root = root.leftroot = stack.pop()k -= 1if k == 0: return root.valroot = root.right
199 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

返回层序遍历数组每层的最后一个值;

class Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if root is None:return []quece, result = [root], []while quece:     length = len(quece)                       tmp_res = [] for i in range(length):node = quece.pop(0)tmp_res.append(node.val)    # if i == length-1: result.append(node.val) if node.left:quece.append(node.left)if node.right:quece.append(node.right)result.append(tmp_res[-1])                                return result
114. 二叉树展开为链表

给你二叉树的根结点 root ,请你将它展开为一个单链表:

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
  • 展开后的单链表应该与二叉树 先序遍历 顺序相同。

方法一:颜色标记法:出栈要求中-前-后,入栈则是右-前-中

需要创建虚拟链表头结点;

class Solution(object):def flatten(self, root):""":type root: TreeNode:rtype: None Do not return anything, modify root in-place instead."""white, black = 0, 1stack = [(white, root)]head = TreeNode(0)pre_node = headwhile stack:color, node = stack.pop()if color == white:if node.right:stack.append((white, node.right))if node.left:stack.append((white, node.left))stack.append((black, node))else:node.left = Nonepre_node.right = nodepre_node = nodereturn head.right

方法二:找到链表的前置节点

对于当前节点,需要将其左子树的根节点移到右侧才能满足链表要求,而其右子树的根节点在链表中需要接在左子树最右结点之后。

class Solution(object):def flatten(self, root):""":type root: TreeNode:rtype: None Do not return anything, modify root in-place instead."""node = rootwhile node:if node.left:left_node = left_last_node = node.leftwhile left_last_node.right:left_last_node = left_last_node.rightleft_last_node.right = node.rightnode.left = Nonenode.right = left_nodenode = node.rightreturn root
105 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

前序遍历:中-左-右

中序遍历:左-中-右

前序遍历的第一个元素为根节点,在中序遍历序列找到根节点后就能将元素二分为左子树元素和右子树元素,再在前序遍历序列中找到左子树的根节点和右子树的根节点,...

class Solution(object):def buildTree(self, preorder, inorder):""":type preorder: List[int]:type inorder: List[int]:rtype: TreeNode"""def bulidThree(preorder, inorder):if preorder:root = TreeNode(preorder[0])idx = inorder.index(preorder[0])inorder_left = inorder[:idx]inorder_right = inorder[idx+1:]preorder_left = preorder[1:idx+1]preorder_right = preorder[idx+1:]root.left = bulidThree(preorder_left, inorder_left)root.right = bulidThree(preorder_right, inorder_right)return rootelse:returnreturn bulidThree(preorder, inorder)

每次查找根节点坐标会造成时间浪费,可以用hashmap存储(空间换时间)

437 路径总和III

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

统计从根节点出发到每个子节点的数值和,用不同节点的数值和做差得到截选的路径(类似前缀和想法)

需要在退出当前节点时更新前缀和(保证路径方向向下)

class Solution(object):def pathSum(self, root, targetSum):""":type root: TreeNode:type targetSum: int:rtype: int"""global outcur_sum, out = 0, 0hash = {0:1}             # 初始化,不然根节点与目标值相等时只能插入hashdef partSum(root, targetSum, hash, cur_sum):if root is None: return 0global outcur_sum += root.valif targetSum - cur_sum in hash: out += hash[targetSum-cur_sum]if cur_sum in hash:hash[cur_sum] += 1      # 有正有负,会出现重复的前缀和else:hash[cur_sum] = 1partSum(root.left, targetSum, hash, cur_sum)partSum(root.right, targetSum, hash, cur_sum)hash[cur_sum] -= 1cur_sum -= root.valpartSum(root, targetSum, hash, cur_sum)return out
236 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

对于当前节点,若能从其左子树中找到p/q并从其右子树中找到q/p,则该节点为最近公共祖先节点;

若左侧无p/q,则pq均在右子树,将当前节点切换到当前右子节点;

终止条件:切换到叶子节点或找到p/q;

class Solution(object):def lowestCommonAncestor(self, root, p, q):""":type root: TreeNode:type p: TreeNode:type q: TreeNode:rtype: TreeNode"""if root==p or root==q or root==None: return rootleft=self.lowestCommonAncestor(root.left,p,q)right=self.lowestCommonAncestor(root.right,p,q)if left and right:return rootif left and right==None:return leftif right and left==None:return right
124 二叉树的最大路径和

二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。路径和 是路径中各节点值的总和。给你一个二叉树的根节点 root ,返回其 最大路径和 。

和543相似的思路,只是不再记录深度而是路径和;

class Solution(object):def maxPathSum(self, root):""":type root: TreeNode:rtype: int"""global max_sum max_sum = -1001     # 题目给出的节点的值的下界def partPathSum(root):if root is None:return 0left = partPathSum(root.left)left = max(left, 0)                # 除去负值right = partPathSum(root.right)right = max(right, 0)global max_summax_sum = max(max_sum, root.val+left+right)return root.val+max(left, right)partPathSum(root)return max_sum

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

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

相关文章

ffmpeg拉流并解码

流程 注意事项 版本不同导致的api差异资源安全释放

激光焊接机在不锈钢三角阀制造中的应用与发展

不锈钢三角阀激光焊接机是一种专门用于焊接不锈钢三角阀的高效、精准设备。这种设备在不锈钢三角阀的制造过程中起到了至关重要的作用&#xff0c;其应用主要体现在以下几个方面&#xff1a; ​ 一、激光焊接机在不锈钢三角阀制造中的应用 激光焊接机以其独特的优势&#xff…

力扣450 删除二叉搜索树中的节点 Java版本

文章目录 题目描述思路代码 题目描述 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。 一般来说&#xff0c;删除…

【CKA模拟题】如何发布一个SVC资源

题干 For this question, please set this context (In exam, diff cluster name) kubectl config use-context kubernetes-adminkubernetesYou have an existing Nginx pod named nginx-pod . Perform the following steps: Expose the nginx-pod internally within the cl…

Gorm连接Mysql数据库及其语法

Gorm连接Mysql数据库及其语法 文章目录 Gorm连接Mysql数据库及其语法前期工作找到Gorm的github项目简单了解相关MySQL语法 启动数据库定义数据库模型注意点Gorm Model定义结构体标签(tag)支持的结构体标记&#xff08;Struct tags&#xff09;关联相关标记&#xff08;tags&…

openGauss学习笔记-251 openGauss性能调优-使用Plan Hint进行调优-行数的Hint

文章目录 openGauss学习笔记-251 openGauss性能调优-使用Plan Hint进行调优-行数的Hint251.1 功能描述251.2 语法格式251.3 参数说明251.4 建议251.5 示例 openGauss学习笔记-251 openGauss性能调优-使用Plan Hint进行调优-行数的Hint 251.1 功能描述 指明中间结果集的大小&a…

产品经理面试自我介绍,这3大错误千万别犯!

金三银四求职季&#xff0c;你是不是也有面试的冲动&#xff01;但面试并不是头脑一热就能取得好结果&#xff0c;在此之前&#xff0c;必须得有周全的准备&#xff0c;才能应对好面试官的“连环问”&#xff01; 所以&#xff0c;今天这篇产品经理面试干货分享给大家~ 今天文…

最大的开源大模型:马斯克的Grok-1可供企业商用

由马斯克xAI团队研发的最大的开源大语言模型Grok-1&#xff0c;从头开始训练的总参数量为314B&#xff08;3140亿&#xff09;的混合专家&#xff08;MoE&#xff09;模型&#xff0c;其规模超过ChatGPT-3.5&#xff0c;目前Grok背后代码和权重架构已全部开放上线在GitHub。 下…

SqlServer服务启动报错10013

错误提示&#xff1a;MSSQLSERVER 服务启动异常不错10013 Windows不能在本地计算机启动SQLServer(MSSQLSERVER)。有关更多信 息&#xff0c;查阅系统事件日志。如果这是非Microsoft服务&#xff0c;请与服务厂商联系&#xff0c;并 参考特定服务错误代码10013。 解决 1、先禁用…

蓝桥杯 2023 省A 颜色平衡树

树上启发式合并是一个巧妙的方法。 dsu on tree&#xff0c;可以称为树上启发式合并&#xff0c;是一种巧妙的暴力。用一个全局数组存储结果&#xff0c;对于每棵子树&#xff0c;有以下操作&#xff1a; 先遍历轻儿子&#xff0c;处理完轻儿子后将数组清零&#xff08;要再…

网络七层模型之数据链路层:理解网络通信的架构(二)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Linux相关命令(1)

1、找出文件夹下包含 “aaa” 同时不包含 “bbb”的文件&#xff0c;然后把他们重新生成一下。要求只能用一行命令。 find ./ -type f -name "*aaa*" ! -name "*bbb*" -exec touch {} \;文件系统操作命令 df&#xff1a;列出文件系统的整体磁盘使用情况 …

小孔平板应力集中问题matlab有限元编程【源码+PPT讲义】|三节点三角形单元|平面单元|稀疏矩阵 |Comsol网格

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

样本投递技术

投递技术 APT 组织主要以邮件作为投递载体&#xff0c;邮件的标题、正文和附件都可能携带恶意代码。主要的方式是附件是漏洞文档、附件是二进制可执行程序和正文中包含指向恶意网站的超链接这三种。 APT攻击的载荷类型&#xff1a; 文档类&#xff1a;主要是office文档、pdf文…

数组——LEETCODE的第35题(二分法与lower_bound函数)

数组——LEETCODE的第35题&#xff08;二分法与lower_bound函数&#xff09; 本文主要是根据leetcode 35题所写的关于数组的相关内容&#xff0c;主要包括&#xff1a; 数组的的特性leetcode第35题二分法的解题lower_bound函数的使用 文章目录 数组——LEETCODE的第35题&#x…

面试题(一)

目录 1.JDK、JRE、JVM之间的区别 2.hashcode()和equals()的区别 3.String、StringBuffer、StringBuilder的区别 4.泛型中extends和super的区别 5.和equals()的区别 6.重写和重载的区别 7.List和Set的区别 8.ArrayList和LinkedList区别 9.谈谈ConcurrentHashMap的原理 …

LangChain核心模块 Retrieval——文档加载器

Retrieval ​ 许多LLM申请需要用户的特定数据&#xff0c;这些数据不属于模型训练集的一部分&#xff0c;实现这一目标的主要方法是RAG(检索增强生成)&#xff0c;在这个过程中&#xff0c;将检索外部数据&#xff0c;然后在执行生成步骤时将其传递给LLM。 ​ LangChain 提供…

Unsafe的CAS操作及线程park与unpark

如下是一个参照AQS进行的一个加锁及解锁的简单实现&#xff1a; 多线程并发进行同步业务操作&#xff1b;加锁&#xff1a;尝试进行cas 0->1操作&#xff1b;如果加锁成功则进行业务处理&#xff0c;然后进行锁释放 1->0&#xff0c;然后将列头的线程进行唤醒&#xff1…

GDAL中的地理坐标系、投影坐标系及其相互转换

目录 地理坐标系 国内常用地理坐标系 投影坐标系 国内常用投影坐标系&#xff08;不推荐使用&#xff09; 坐标转换 地理坐标转为投影坐标 投影坐标转为地理坐标 地理坐标系 原理参考这篇文章&#xff1a;地理坐标系与投影坐标系区别与联系 https://yunxingluoyun.blog.…