前序遍历

模拟76

a 夏天 提交于 2019-12-01 15:08:38
$T1.$   一开始想简单了。   非常快得码完,刚交上去就发现自己好像伪了。。。。   然后发现有一档部分分$A*B=N$,可以非常简单地构造。   然后就想到正解了。 $T2.$   我们可以发现,在大部分情况下,答案都是连续的。   那么我们只需要考虑,答案在什么地方会断开。   显然只有相邻两个能被拼出的数$a_i$,$a_j$,并且$a_j$比$a_i$的2倍更大时才会出现不合法。   进一步观察可以发现,这种情况只会出现在$a_i$为某些数的和,$a_j$为一个数时。   于是排完序,前缀和扫一遍就没了。 $T3.$   考试的时候一直在想,前序遍历是啥。。。   然后突然发现前序遍历好像就是$dfs$序,也就是说,每个点的子树序号是连续的一段。。。   然后就可以设计$dp$转移了。   另外,由于我考场上没有想到怎么保证合法,所以只能拿$bitset$判断合法性,极限数据跑了$3.5s$,然后我手写了$bitset$,它就从$3.5s$直接砍到了$1.2s$。甚至跑的比某些$O(n^3)$还快。。。。    手写bitset牛逼bitset复杂度是O(1)的 来源: https://www.cnblogs.com/hzoi-cbx/p/11689934.html

LeetCode-144 二叉树的前序遍历

南笙酒味 提交于 2019-12-01 09:56:54
问题: 如标题 分析:   非递归前序遍历和后序遍历一样,唯一不同的两个点是: 1.后序遍历需要头插,所以只能用链表(linkedlist) 2.左右节点判断是否为空的顺序颠倒。 除了以上两点以外其他代码完全相同。 代码: /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> listTree = new ArrayList(); if(root==null){ return listTree; } Stack s = new Stack(); TreeNode node; s.push(root); while(!s.empty()){ node = (TreeNode)s.pop(); listTree.add(node.val); if(node.right!=null){ s.push(node.right); } if(node.left!=null){ s

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

北城以北 提交于 2019-12-01 03:19:13
public class Solution { int i=0; public TreeNode reConstructBinaryTree(int [] pre,int [] in) { return constructBiTree(pre,in,0,pre.length-1); } public TreeNode constructBiTree(int pre[],int in[],int start,int end){ if(start>end) return null; TreeNode node = new TreeNode(pre[i]); int index=Location(pre[i],in); i++; if(i>=pre.length) return node; node.left=constructBiTree(pre,in,start,index-1); node.right=constructBiTree(pre,in,index+1,end); return node; } public int Location(int target,int in[]){ int i=0; for( i=0;i<in.length;i++){ if(target==in[i]) break; } return i; } } 来源: oschina 链接: https:

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

落花浮王杯 提交于 2019-12-01 03:16:14
public class Solution { int i=0; public TreeNode reConstructBinaryTree(int [] pre,int [] in) { return constructBiTree(pre,in,0,pre.length-1); } public TreeNode constructBiTree(int pre[],int in[],int start,int end){ if(start>end) return null; TreeNode node = new TreeNode(pre[i]); int index=Location(pre[i],in); i++; if(i>=pre.length) return node; node.left=constructBiTree(pre,in,start,index-1); node.right=constructBiTree(pre,in,index+1,end); return node; } public int Location(int target,int in[]){ int i=0; for( i=0;i<in.length;i++){ if(target==in[i]) break; } return i; } } 来源: oschina 链接: https:

二叉树遍历的几种实现

試著忘記壹切 提交于 2019-11-30 23:22:38
用c++是实现的二叉树的存储以及几种遍历方法 #include<iostream> #include<cstdlib> #include<stack> //使用stl中的栈模板 using namespace std; typedef struct BNode{ //定义节点的结构体 char data; //数据部分 BNode* Lc; //左孩子 BNode* Rc; //右孩子 }Bitree,*pBitree; pBitree CreatTree(pBitree root){ //利用递归存树 char c; cin>>c;//输入节点数据 if(c!='#'){ root = (pBitree)malloc(sizeof(Bitree)); root->data=c; root->Lc=CreatTree(root->Lc); root->Rc=CreatTree(root->Rc); } else root = NULL; return root; } void norecursionInorder1(pBitree root){ //不用递归的中序遍历1 stack<pBitree> st; pBitree p; st.push(root); while(!st.empty()){ while(st.top()!=NULL) { p=st.top(); st

图解数据结构-树及树的遍历

末鹿安然 提交于 2019-11-30 14:58:14
当你第一次学习编码时,大部分人都是将数组作为主要数据结构来学习。 之后,你将会学习到哈希表。如果你是计算机专业的,你肯定需要选修一门数据结构的课程。上课时,你又会学习到链表,队列和栈等数据结构。这些都被统称为线性的数据结构,因为它们在逻辑上都有起点和终点。 当你开始学习树和图的数据结构时,你会觉得它是如此的混乱。因为它的存储方式不是线性的,它们都有自己特定的方式存储数据。 定义 树是众所周知的非线性数据结构。它们不以线性方式存储数据。他们按层次组织数据。 树的定义 树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。 在任意一颗非空树中: (1) 有且仅有一个 特定的称为根(Root)的结点。 (2)当n>1时,其余结点可分为m(m>0)个 互不相交的有限集 T1、T2、.....、Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。 下图就符合树的定义: 其中根结点A有两个子树: 我们硬盘的文件系统就是很经典的树形结构。 “树”它具有以下的特点: ①每个节点有零个或多个子节点; ②没有父节点的节点称为根节点; ③每一个非根节点有且只有一个父节点; ④除了根节点外,每个子节点可以分为多个不相交的子树; 树( tree )是被称为结点( node )的实体的集合。结点通过边( edge )连接。每个结点都包含值或数据( value/date )

二叉树搜索树中序遍历下的前驱节点与后继节点

守給你的承諾、 提交于 2019-11-30 13:34:31
前驱节点 前驱节点的值小于该节点的值,是该节点左子树中值最大的 后继节点 后继节点的值大于该节点的值,是该节点右子树中值最小的 因为二叉搜索树的中序遍历出来的结果就是一棵树节点上的值的升序排序,所以一个数的前驱节点的值就是比它小一个的数,后继节点的值就是比它大一个的节点 找前驱节点有以下情况: (1) 该节点有左子树,那么该节点的前驱节点就是其左子树中最大的那个。例如 10 它有左孩子,它的前驱节点就是左孩子中最大的也就是 8 。 (2) 该节点没有左子树,那么就又有两种情况: 1. 该节点是其父节点的右孩子,那么它的前驱就是他的父节点; 例如 17 它的前驱就是16 2. 该节点是其父节点的左孩子,那么就得往其祖辈寻找直到找到它祖辈是左孩子为止,如果没找到,那么说明该节点没有前驱节点。 例如 8 它是左孩子,所以它的前驱不是它的父亲,就得往上找, 而它的父亲是他爷爷的右孩子,所以 8 的前驱就应该是它的爷爷 7 。 找后继节点有以下情况: (1) 该节点有右子树,那么该节点的后继节点就是其右子树中最小的那个。例如 10 它有右子树 它的后继就是右子树中最小的那个 14 。 (2) 该节点没有右子树,那么它的后继节点也要往祖辈里面找,也是分两种情况 : 1. 该节点是其父节点的左子树,那么它的后继节点就是他的父亲; 2. 该节点是父节点的左子树, 那么往上找

二叉树的遍历算法

大城市里の小女人 提交于 2019-11-30 12:05:43
遍历(Traverse) 就是按照某种次序访问树中的所有结点,且每个结点恰好访问一次 也就是说,按照被访问的次序,可以得到由树中所有结点排成的一个序列 树的遍历也可以看成是人为的将非线性结构线性化 这里的“访问”是广义的,可以是对结点作各种处理,例如输出结点信息、更新结点信息等 在我们的现实中,并不真正的“访问”这些结点,而是得到一个结点的线性序列,以线性表的形式输出 将整个二叉树看做三部分:根、左子树、右子树。如果规定先遍历左子树、在遍历右子树,那么根据根的遍历顺序就有三种遍历方式: 左子树 右子树 根 先序/根遍历DLR:根 左子树 右子树 中序/根遍历LDR:左子树 根 右子树 后序/根遍历LRD:左子树 右子树 根 注意:由于树的递归定义,其实对三种遍历的概念其实也是一个递归的描述过程 先序/根遍历DLR:1 4 5 2 3 6 7 中序/根遍历LDR:4 5 1 3 2 6 7 后序/根遍历LRD:5 4 3 7 6 2 1 如果按层次遍历,没有递归 面试题:已知一棵二叉树的后序遍历的序列为5 4 3 7 6 2 1,中序遍历的序列为4 5 1 3 2 6 7,则其先序遍历的序列是什么? 只要给定中序遍历,先序遍历或者后序遍历再给一个,就可以求出另一个 后序遍历最后肯定是根,所以确定1是根 所以4 5是左子树,3 2 6 7是右子树 依此类推 /** *二叉链表的结点 *

二叉树遍历问题、时间空间复杂度、淘汰策略算法、lru数据结构、动态规划贪心算法

我与影子孤独终老i 提交于 2019-11-30 09:19:58
二叉树的前序遍历、中序遍历、后序遍历 前序遍历 遍历顺序规则为【根左右】 ABCDEFGHK 中序遍历 遍历顺序规则为【左根右】 BDCAEHGKF 后序遍历 遍历顺序规则为【左右根】 DCBHKGFEA 什么是时间复杂度和空间复杂度 时间复杂度 是指执行当前算法所消耗的时间 空间复杂度 是指执行当前算法需要占用多少内存空间 评价一个算法的效率主要是看它的时间复杂度和空间复杂度。然后有时候鱼和熊掌不可得兼,所以我们就需要从中去取一个平衡点 知道淘汰策略的哪些算法? lru算法如果让你实现你会选择哪种数据结构 LRU算法的原理(least recently used,最近最少使用): LRU的四种实现方式 LRU-K 原理:LRU-K中的K代表最近使用的次数,因此LRU可以认为是LRU-1。LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题,其核心思想是将“最近使用过1次”的判断标准扩展为最近使用过K次 实现:相比于LRU,LRU-K需要多维护一个队列,用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候,才会将数据放入到缓存中。当需要淘汰数据的时候,LRU-K后淘汰第K次访问时间据当前时间最大的数据。 过程 数据第一次被访问,加入到访问历史列表 如果数据在访问历史列表里后没有达到K次访问,就按照一定的规则(FIFO,LRU)淘汰

学习笔记之二叉树的遍历

空扰寡人 提交于 2019-11-30 05:47:19
分层遍历 将每一层的节点遍历出来,利用 LinkedList ,先压入根节点,循环遍历,循环的同时再将左节点,右节点分别加到尾部. // 分层遍历 (TreeNode root) if ( root == null ) return ; LinkedList < TreeNode > nodes = new LinkedList < > ( ) ; TreeNode last = root ; TreeNode nLast = root ; nodes . push ( root ) ; while ( ! nodeStack . isEmpty ( ) ) { TreeNode node = nodes . pop ( ) ; System . out . print ( node . data + " " ) ; if ( node . left != null ) { nodes . add ( node . left ) ; nLast = node . left ; } if ( node . right != null ) { nodes . add ( node . right ) ; nLast = node . right ; } if ( node == last ) { System . out . println ( " " ) ; last = nLast