算法(14)-数据结构-二叉树

leetcode-explore-learn-数据结构-二叉树1

  • 0.概述
  • 1.深度优先遍历dfs
    • 1.1先序遍历-中左右
    • 1.2中序遍历-左中右
    • 1.3后序遍历-左右中
  • 2.广度优先遍历bfs
  • 3.遍历-常见问题
    • 3.1 二叉树的最大深度
      • 自顶向下
      • 自底向上
    • 3.2对称二叉树
    • 3.3路径总和
  • 4.重构-常见问题
    • 4.1根据中序和后序遍历序列构造二叉树
    • 4.2根据前序和中序遍历序列构造二叉树
    • 4.3填充每个节点的下一个右侧节点指针
    • 4.4填充每个节点的下一个右侧节点指针2
    • 4.5二叉树的最近公共祖先
    • 4.6二叉树的序列化和反序列化
  • 5.other
    • 5.1翻转二叉树
    • 5.2合并两棵二叉树

note for :https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/7/

0.概述

二叉树节点结构(所有例题的编程语言为python):

class TreeNode(object):def __init__(self, x):self.val = xself.left = Noneself.right = None

树结构本身是递归定义的:一个节点,包含一个值和一个指向其他节点的列表。树的定义天然带有递归的属性,树的许多问题可以通过递归的方式来解决。对于每一个递归层级,我们只需要关注单个节点内的问题,然后通过递归调用来解决其子节点问题。

二叉树是一种典型的树状结构,每个节点最多有两个子树的树,通常被称作“左子树”和“右子树”。

二叉树用来存储具有树结构的数据,我们通过访问树的各个结点来进行数据处理。可以逐层访问树节点【广度优先-Breadth First Search-BFS】,又叫层次遍历。也可以逐条路径(每一个可能的分支路径深入到不能再深入为止)访问结点【深度优先-Depth First Search-DFS】。
其中 深度优先 按照根节点被访问到的顺序,又可分为:【先序遍历】、【中序遍历】、【后序遍历】。

广度优先/深度优先 遍历都各自拥有【迭代】和【递归】两种代码实现方式。
迭代:找一种容器【队列/堆栈】存放暂时未访问到的节点,等到访问它了再把它弹出来。迭代退出条件是:容器是空的,即没有未被访问过的结点,即所有节点都被访问过了。
递归:需要存在递归函数和原函数,原函数中开启递归入口,递归函数不断递归求解。递归退出条件-如果节点为空,无需再往下递归。

二叉树常见的问题(遍历二叉树能够做啥):
二叉树的最大深度:理解【自顶向上】、【自底向上】递归的经典例子。
对称二叉树:
路径综总和:

1.深度优先遍历dfs

深度优先 按照根节点被访问到的顺序可分为:【先序遍历】、【中序遍历】、【后序遍历】。

1.1先序遍历-中左右

递归的框架有了,如何在res list中加入答案,在内层再定义一个函数,

class Solution(object):def preorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res=[]def dfs_pre(node):if node==None:returnres.append(node.val)dfs_pre(node.left)dfs_pre(node.right)dfs_pre(root)return res

迭代的框架:当前节点的右子树放入堆栈,存起来。将当前节点的值放入res,当前节点更新为当前节点的左子树节点。

class Solution(object):def preorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""stack=[]res=[]node=rootwhile(node or stack):if node:res.append(node.val)if node.right:stack.append(node.right)node=node.leftelse:node=stack.pop()return res

1.2中序遍历-左中右

递归的框架和先序遍历一样。

class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res=[]def dfs_inorder(node):if node==None:returndfs_inorder(node.left)res.append(node.val)dfs_inorder(node.right)dfs_inorder(root)return res

迭代框架:需要将什么放stack中呢,根节点一路向左遍历到底部。将根节点都放进去,放进去的就是有的节点。遍历到底端之后,逐个弹出;然后去该节点的右子树,如果右子树为空,就会弹该节点的父亲节点;如果右子树不为空,就可以迭代进去处理右子树。

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

1.3后序遍历-左右中

递归的框架和先序,中序遍历一致

class Solution(object):def postorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""res=[]def dfs_post(node):if node==None:returndfs_post(node.left)dfs_post(node.right)res.append(node.val)dfs_post(root)return res

迭代的框架:中右左的逆序,就是左右中。在伪前序遍历(保存左节点)的结果下,逆序输出即可。

class Solution(object):def postorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""stack=[]res=[]node=rootwhile(stack or node):if node:res.append(node.val)if node.left:stack.append(node.left)node=node.rightelse:node=stack.pop()return res[::-1]

2.广度优先遍历bfs

层次遍历,用队列来帮助实现广度优先遍历

递归框架: 需要有一个level信息用于存储该节点所处的层次。问题:在哪里新增res的层次呢–解决方案,先判断l层次是否存在,不在的话新增。

class Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if root==None:return []res=[]def bfs(node,l):if node==None:returnif l>len(res)-1:res.append([])res[l].append(node.val)bfs(node.left,l+1)bfs(node.right,l+1)bfs(root,0)return res

迭代框架:队列,先进先出,每层先统计队列的长度,确认要弹出的元素个数。

class Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if root==None:return []que=[root]res=[]l=0while(que):n=len(que)res.append([])for i in range(n):node=que.pop(0)res[l].append(node.val)if node.left:que.append(node.left)if node.right:que.append(node.right)l+=1return res  

3.遍历-常见问题

树的问题,就是遍历所有节点找出一个答案喽。拿到问题,先考虑-深度优先?广度优先;然后再考虑用递归?迭代。

3.1 二叉树的最大深度

一道题带你理解什么是自顶向上/自底向上–二叉树的最大深度
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

自顶向下

自顶向下 :在每个递归层级上,先访问节点来计算一些值,并在递归调用时将这些值传递给子节点。自顶向下的方案可以看作是一种先序遍历

根节点的深度是1,对于一个节点其深度为x, 那么我们将知道其子节点的深度。在递归调用时自顶向下将节点的深度作为一个参数传递下去。每一个节点都知道自己的深度,对于叶子节点,可以通过比较确定需不需要更新更大的深度。

class Solution(object):def __init__(self):self.res=0def maxDepth(self, root):""":type root: TreeNode:rtype: int"""def dfs_top_down(node,l):if node==None:     # root 本身就是一个空指针returnif node.left==None and node.right==None:self.res=max(self.res,l)          # 用max 需要重新定义一个全局变量dfs_top_down(node.left,l+1)dfs_top_down(node.right,l+1)dfs_top_down(root,1)return self.res

自底向上

自底向上:在每个递归层级上,对所有的节点递归调用函数,然后根据返回值和根节点本身的值得到答案。自底向上的方案可以看作后序遍历

如果知道一个根节点,以其左子节点为根的最大深度为l,以其右子节点为根的最大深度为如,那么这个根节点所在子树的最大深度为max(l,r)+1max(l,r)+1max(l,r)+1(对于每个节点的答案,都可以在解决它的子节点问题的大难之后得到答案)

class Solution(object):def maxDepth(self, root):""":type root: TreeNode:rtype: int"""def dfs_bottom_up(node):if node==None:return 0left_l=dfs_bottom_up(node.left)right_l=dfs_bottom_up(node.right)return max(left_l,right_l)+1res=dfs_bottom_up(root)return res 

树递归框架的小结:
自顶向上:需要使用一些参数和节点本身的值来决定传递给子节点参数
自底向上:如果知道子节点的答案就能知道该节点的答案,采用自底向上是个不错的选择

自底向上/自顶向上-都是深度优先递归,想要用深度优先迭代解需要将节点的层级状态存下来。
如果使用广度优先-无论是迭代,还是递归。res list 的层数就是最大深度。

3.2对称二叉树

给定一个二叉树,检查它是否为镜像对称。
解题关键:每次取到需要相互比较的两个节点。

递归:所以两个指针分别从根节点开始,一个往左子树游走,一个往右子树游走,依次查看镜面对称的节点是相等。也就是官方题解种所说的:验证root 子树和root子树是不是镜面对称的。如果是的话,单独的一棵root树是镜面对称的。

class Solution(object):def isSymmetric(self, root):""":type root: TreeNode:rtype: bool"""def ismirror(node1,node2):if node1==None and node2==None:return Trueif node1==None or node2==None:return Falsereturn node1.val==node2.val and ismirror(node1.left,node2.right) and ismirror(node1.right,node2.left)flag=ismirror(root,root) # root 和root为镜像,root自己本身为镜像return flag

迭代:队列初始化为[root,root],将需要比较的点放在相邻位置。每次弹出两个节点,如果两个节点相同时,node1.left 和node2.right 放入队列;将node1.right与node2.left放入队列。这样押入弹出直至对比完该对比的节点。

class Solution(object):def isSymmetric(self, root):""":type root: TreeNode:rtype: bool"""que=[root,root]while(que):node1=que.pop(0)node2=que.pop(0)if node1==None and node2==None:continueif node1==None or node2==None:return Falseif node1.val!=node2.val:return Falseque.append(node1.left)que.append(node2.right)que.append(node1.right)que.append(node2.left)return True

3.3路径总和

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。【深度优先】

递归:直觉上至顶向下,是可行的思路。在每个节点处将目标值-节点值,将这个差值传给下一个节点,不断重复,如果叶子节点处刚好减为0,说明存在一条路径使得该路径上所有节点的值相加等于目标和。递归函数应该返回True 或者False 程序实现上可以遍历所有的路径,将所有的结果取或,但是只有一个为True 其实递归就可以终止,这个该怎么写。

class Solution(object):def hasPathSum(self, root, sum):""":type root: TreeNode:type sum: int:rtype: bool"""def has_top_down(node,target):if node==None:return Falseif node.left==None and node.right==None:if target-node.val==0:return Trueif has_top_down(node.left,target-node.val):return Trueif has_top_down(node.right,target-node.val):return Truereturn Falsereturn has_top_down(root,sum)

迭代:维护一个堆栈,用于储存每一个节点和其需要匹配的信息。每次从堆栈中弹出一个节点,判断该节点是否为叶子节点,如果为叶子节点,则判断对应的目标值-节点值是否为0;如果该节点不为叶子节点,将其子节点和相应的信息押入堆栈中。–堆栈如此维护:深度优先遍历的结构,遍历完一条路径之后再去遍历其他的路径。第一条走过的是最右边的路径,是一个由右往左扫描的过程。

class Solution(object):def hasPathSum(self, root, sum):""":type root: TreeNode:type sum: int:rtype: bool"""if root==None:return Falsestack=[(root,sum)]while(stack):node,target=stack.pop()if node.left==None and node.right==None and node.val-target==0:return Trueif node.left:stack.append((node.left,target-node.val))if node.right:stack.append((node.right,target-node.val))return False

4.重构-常见问题

4.1根据中序和后序遍历序列构造二叉树

inorder=[9,3,15,20,7] 左根右
postorder=[9,15,7,20,3] 左右根,逆序就是根右左:[3,20,7,15,9]
由后序遍历中可知根节点是3,在中序遍历中可以确定左右子树序列是多少。如何提取下一个根节点呢?取根和左右子树递归构造该如何衔接。
inorder 用来控制递归出口
postorder 才是提供根节点的源泉。

class Solution(object):def __init__(self):self.root_idx = 0def buildTree(self, inorder, postorder):""":type inorder: List[int]:type postorder: List[int]:rtype: TreeNode"""postorder_inver = postorder[::-1]def helper(left_idx=0, right_idx=len(postorder)):if left_idx == right_idx:return Noneroot_val = postorder_inver[self.root_idx]self.root_idx += 1root = TreeNode(root_val)# 只有一个节点时[a], inorder_idx = 0, left_idx=0, inorder_idx+1=1,# 左右节点调用都返回Noneinorder_idx = inorder.index(root_val)root.right = helper(inorder_idx+1, right_idx)root.left = helper(left_idx, inorder_idx)return rootreturn helper()

4.2根据前序和中序遍历序列构造二叉树

preorder=[3,9,20,15,7] 中左右
inorder=[9,3,15,20,7] 左中右
一个根节点可以将中序遍历划分为左一半,右一半。
全局变量pre_idx,每次运行一次helper函数一次加1,取下一根节点;直至左子树运行完,对应的根节点下标也应该遍历完全了。
剩余问题:index不因该是根节点的在中序遍历中的下标么?左子树包含的内容不是应该为[0,index-1] 根递归出口有关,不是直接索引元素。

class Solution(object):def __init__(self):self._root_idx = 0def buildTree(self, preorder, inorder):""":type preorder: List[int]:type inorder: List[int]:rtype: TreeNode"""# 前序-中左右, 中序-左右中def helper(left_idx=0, right_idx=len(inorder)):if left_idx == right_idx:return Noneroot_val = preorder[self._root_idx]self._root_idx += 1root = TreeNode(root_val)inorder_idx = inorder.index(root_val)root.left = helper(left_idx, inorder_idx)root.right = helper(inorder_idx+1, right_idx)return rootreturn helper()

4.3填充每个节点的下一个右侧节点指针

填充一个完美二叉树的每个解答的每个节点的下一个右侧节点。完美二叉树说的是,所有叶子节点都在同一层。

思路:关键找到每一个节点的下一个节点,那不就是二叉树的层次遍历。
每层的节点的next指针指其下一个节点,用l来控制该层的最后一个节点指向None。

class Solution(object):def connect(self, root):""":type root: Node:rtype: Node"""if root == None:return rootnode_que = [root]while(node_que):level_node_num = len(node_que)i = 0while(node_que and i < level_node_num):node = node_que.pop(0)if i < level_node_num - 1:node.next = node_que[0]if node.left:      # 左右节点同时存在,所以只需要判断一个非空即可node_que.append(node.left)node_que.append(node.right)i+=1return root

4.4填充每个节点的下一个右侧节点指针2

给定一个二叉树,填充它每个next指针指向右侧节点,同一层的最右侧节点填充为None.
思路:不是一棵完美的二叉树,不过还是树的层次遍历,上一题的框架依旧可以使用。
代码只diff 了一行

"""
# Definition for a Node.
class Node(object):def __init__(self, val=0, left=None, right=None, next=None):self.val = valself.left = leftself.right = rightself.next = next
"""class Solution(object):def connect(self, root):""":type root: Node:rtype: Node"""if root == None:return rootnode_que = [root]while(node_que):level_node_num = len(node_que)i = 0while(node_que and i < level_node_num):node = node_que.pop(0)if i < level_node_num - 1:node.next = node_que[0]if node.left:node_que.append(node.left)if node.right:      //4.4diff行node_que.append(node.right)i+=1return root

4.5二叉树的最近公共祖先

给定一个二叉树,找到该树中两个指定节点的最近公共祖先。
官方思路1:递归
递归遍历整棵树,定义fxf_xfx表示x节点的子树中是否包含p节点或者q节点,如果包含则为true.采用自底向上从叶子节点开始更新,保证满足条件的公共祖先深度最深。

class Solution(object):def __init__(self):self.ans = Nonedef lowestCommonAncestor(self, root, p, q):def bottom_up(node):if node == None:return Falseleft_mark = bottom_up(node.left)  # 左右子树中是否包含pq节点right_mark = bottom_up(node.right)current_mark = (node.val == p.val) or (node.val == q.val)# print(node.val, left_mark, right_mark, current_mark)if (current_mark + left_mark + right_mark == 2):self.ans = nodereturn Truereturn current_mark or right_mark or left_markbottom_up(root)return self.ans

官方思路2:储存父节点
用hash表存储所有节点的父亲节点,然后利用节点的父亲节点的信息从p往上跳,直至根节点,记录已经访问过的节点;再从q节点开始不断往上跳,每次上跳一个节点就去p已访问的节点中寻找是否已经访问过该节点。第一次遇到的p已经访问的节点,则该节点为答案。
难点1:父亲节点hash表。{child1:root1,child2:root1},只要遍历过二叉树的所有节点,就可以实现这个。
难点2:从p开始,不断在父亲hash表中找父亲节点,直至找不到父亲节点的跟节点,将所有路径放入[]中。
技巧:还是将节点放进去。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution(object):def __init__(self):self.father_hash = {}self.vist_hash = {}def lowestCommonAncestor(self, root, p, q):def dfs_contruct_father_hash(node):if node == None:return if node.left:self.father_hash[node.left] = nodeif node.right:self.father_hash[node.right] = nodedfs_contruct_father_hash(node.left)dfs_contruct_father_hash(node.right)self.father_hash[root] = Nonedfs_contruct_father_hash(root)node = pwhile(p):self.vist_hash[p] = Truep = self.father_hash[p]node = qwhile(q):if self.vist_hash.get(q):return qq = self.father_hash[q]return None

4.6二叉树的序列化和反序列化

将二叉树序列化为一个字符串,将得到的字符串反序列化为二叉树。
说明:不要使用类成员/全局/静态变量来存储状态,序列化和反序列化算法应该是无状态的。–什么是无状态?

序列化和反序列化递归顺序一致就可以。

class Codec:def serialize(self, root):"""Encodes a tree to a single string.:type root: TreeNode:rtype: str"""def dfs_serialize(node, iter_str):if node == None:iter_str += "None,"return iter_striter_str += "{0},".format(node.val)iter_str = dfs_serialize(node.left, iter_str)iter_str = dfs_serialize(node.right, iter_str)return iter_strreturn dfs_serialize(root, "")def deserialize(self, data):"""Decodes your encoded data to tree.:type data: str:rtype: TreeNode"""def dfs_deserialize(data_list):# print(data_list)if data_list[0] == "None":data_list.pop(0)return Nonenode = TreeNode(int(data_list[0]))data_list.pop(0)node.left = dfs_deserialize(data_list)node.right = dfs_deserialize(data_list)return nodedata_list = data.split(",")return dfs_deserialize(data_list)

5.other

5.1翻转二叉树

递归-自低向上的交换过程

class Solution(object):def invertTree(self, root):if root==None:returnself.invertTree(root.left)self.invertTree(root.right)root.left,root.right=root.right,root.leftreturn root

迭代-自顶向下的交换过程

class Solution(object):def invertTree(self, root):""":type root: TreeNode:rtype: TreeNode"""if root:q=[root]else:return rootwhile(q):curr=q.pop(0)curr.left,curr.right=curr.right,curr.leftif curr.left:q.append(curr.left)if curr.right:q.append(curr.right)return root

5.2合并两棵二叉树

leetcode617: 两棵树有公共结点处的值为两数对应节点值想加

递归

class Solution(object):def mergeTrees(self, t1, t2):if not t1 and not t2:return Noneroot=TreeNode(0)if t1 and t2:root.val=t1.val+t2.valroot.left=self.mergeTrees(t1.left,t2.left)root.right=self.mergeTrees(t1.right,t2.right)elif t1:root.val=t1.valroot.left=self.mergeTrees(t1.left,None)root.right=self.mergeTrees(t1.right,None)else:root.val=t2.valroot.left=self.mergeTrees(None,t2.left)root.right=self.mergeTrees(None,t2.right)return rootclass Solution(object):def mergeTrees2(self, t1, t2):if t1==None:return t2if t2==None:return t1t1.val+=t2.valt1.left=self.mergeTrees2(t1.left,t2.left)t1.right=self.mergeTrees2(t1.right,t2.right)return t1

迭代-首先把两棵树的根节点入栈,栈中的每个元素都会存放两个根节点,并且栈顶的元素表示当前需要处理的节点。
以t1作为最后的输出返回,
当前结点的处理( 在stack里面的东西都是非空的):
两者相加的值放入t1.val
子结点的处理:
t1没有做孩子,t2的左孩子给t1.
t1,t2同时有左孩子,将其同时入栈,
右孩子的处理同理。

class Solution(object):def mergeTrees(self, t1, t2):if t1==None:return t2if t2==None:return t1stack=[(t1,t2)]while(stack):node1,node2=stack.pop() # 在stack里面的东西都是非零的node1.val+=node2.valif node1.left==None:node1.left=node2.leftelif node1.left and node2.left:  # 1.left 和2.left同时非零stack.append([node1.left,node2.left])if node1.right==None:node1.right=node2.right      # 放过来之后就有。elif  node1.right and node2.right:  # 1.left 和2.left同时非零stack.append([node1.right,node2.right])return t1

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

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

相关文章

多进程鱼多线程的权衡选择

最近有好多人在网上问道做游戏开发框架用多线程还是多进程呢,或者两者之间的优缺点,等等类似的问题。下边小高就带您小小分析一下: 1、首先要明确进程和线程的含义:进程(Process)是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一…

leetcode322 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1。 示例 1: 输入: coins [1, 2, 5], amount 11 输出: 3 解释: 11 5 5 1 示例 2: 输入: coins [2],…

给数据减肥 让MySQL数据库跑的更快

在数据库优化工作中&#xff0c;使数据尽可能的小&#xff0c;使表在硬盘上占据的空间尽可能的小&#xff0c;这是最常用、也是最有效的手段之一。因为缩小数据&#xff0c;相对来说可以提高硬盘的读写速度&#xff0c;并且在查询过程中小表的内容处理时所占用的系统资源比较少…

算法(15)-leetcode-explore-learn-数据结构-运用递归解决二叉树的问题

leetcode-explore-learn-数据结构-二叉树2本系列博文为leetcode-explore-learn子栏目学习笔记&#xff0c;如有不详之处&#xff0c;请参考leetcode官网&#xff1a;https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/7/

leetcode538 把二叉搜索树转换成累加树

给定一个二叉搜索树&#xff08;Binary Search Tree&#xff09;&#xff0c;把它转换成为累加树&#xff08;Greater Tree)&#xff0c;使得每个节点的值是原来的节点值加上所有大于它的节点值之和。 对于每一个点来说&#xff0c;自己的父&#xff0c;和自己父的右子树都是大…

AWK常用命令华(1)

awk 调用: 1.调用awk:

AWk的调用精华

awk 的调用方式 awk 提供了适应多种需要的不同解决方案,它们是: 一、awk 命令行,你可以象使用普通UNIX 命令一样使用awk,在命令行中你也可以使用awk 程序设计语言,虽然awk 支持多行的录入,但是录入长长的命令行并保证其正 确无误却是一件令人头疼的事,因此,这种方法一般…

算法(16)-leetcode-explore-learn-数据结构-二叉树总结

leetcode-explore-learn-数据结构-二叉树3本系列博文为leetcode-explore-learn子栏目学习笔记&#xff0c;如有不详之处&#xff0c;请参考leetcode官网&#xff1a;https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/7/所有例题的编程…

leetcode15 三数之和

给定一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;找出所有满足条件且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 例如, 给定数组 nums [-1, 0, 1,…

AWK再次认识--内置的参数,以及编写脚本

原本这是篇给公司内同事写的培训文章&#xff0c;对于初学awk的人还蛮有帮助&#xff0c;贴到这里与大家共享一下。 〇、前言 意见反馈&#xff0c;请mailto:datouwanggmail.com。 一、AWK简介 AWK名字来源于三位创造者Aho、Weinberger和Kernighan统称。 AWK擅长处理文本数据。…

AWk高级编程

首先再说一说awk的工作流程还是有必要的 : 执行awk时, 它会反复进行下列四步骤. 1. 自动从指定的数据文件中读取一个数据行. 2. 自动更新(Update)相关的内建变量之值. 如 : NF, NR, $0... 3. 依次执行程序中所有 的 Pattern { Actions } 指令. 4. 当执行完程序中所有 Pattern {…

leetcode19. 删除链表的倒数第N个节点

给定一个链表&#xff0c;删除链表的倒数第 n 个节点&#xff0c;并且返回链表的头结点。 示例&#xff1a; 给定一个链表: 1->2->3->4->5, 和 n 2. 当删除了倒数第二个节点后&#xff0c;链表变为 1->2->3->5. 说明&#xff1a; 给定的 n 保证是有效…

python模块(5)-Matplotlib 简易使用教程

Matplotlib简易使用教程0.matplotlib的安装1.导入相关库2.画布初始化2.1 隐式创建2.2 显示创建2.3 设置画布大小2.4 plt.figure()常用参数3.plt. 能够绘制图像类型3.1等高线3.2 箭头arrow4.简单绘制小demodemo1.曲线图demo2-柱状、饼状、曲线子图5.plt.plot()--设置曲线颜色,粗…

random_shuffle 和transform算法

1)STL中的函数random_shuffle()用来对一个元素序列进行重新排序(随机的),函数原型如下: std::random_shuffle

C语言字符输出格式化

符号属性 长度属性 基本型 所占 位数 取值范围 输入符举例 输出符举例 -- -- char 8 -2^7 ~ 2^7-1 %c %c、%d、%u signed -- char 8 -2^7 ~ 2^7-1 %c %c、%d、%u unsigned -- char 8 0 ~ 2^8-1 %c %c、%d、%u [signed] short [int] 16 -2^15 ~ 2^15-1 %hd %hd unsigned short […

leetcode20 有效的括号

给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串&#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 注意空字符串可被认为是有效字符串。 示…

python模块(6)-Pandas 简易使用教程

Pandas 简易教程1.Pandas简介2.创建2.1创建dataFrame2.2创建Series3.dataframe数据访问3.1 获取一列--列标签3.2 获取多列--列标签列表3.3 获取一行--行标签.loc()3.4 获取多行--行切片操作.loc()3.5 index 获取行列信息--df.iloc()3.6 获取一个元素3.7 布尔值选择数据4.datafr…

windows 如何查看端口占用情况?

开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PID 之后在任务管理器中找到这个PID所对应的程序如果任务管理器中没有PID这一项,可以在任务管理器中选"查看"-"选择列" 经常,我们在启动应用的时候发现系统需要的端口被别的…

泛型lua的for循环以及lua的特殊的dowhile循环

范型for循环&#xff1a; -- print all values of array a a{1,2,3,4,5,6,7}; for i,v in ipairs(a) do print(v) end 范型for遍历迭代子函数返回的每一个值。 再看一个遍历表key的例子&#xff1a; -- print all keys of table t map {["gaoke"]1,["gaoxin&…

leetcode1 两数之和

给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;你不能重复利用这个数组中同样的元素。 示例: 给定 nums [2, 7, 11, 15], t…