遍历

1111111111111 算法汇总

为君一笑 提交于 2020-02-28 21:01:49
如何找到两个相交链表对交点? 如果两个单向链表有公共节点,则两个链表会构成Y型结构,最后一个节点相同 我们可以从头开始遍历两个链表,找到最后一个节点的指针,设为p_a,p_b。同时记录下两个链表的长度len_a,len_b(假设len_a >= len_b)。 如果p_a == p_b,则说明两个链表有公共节点,否则没有。 如果有公共节点,则第一个公共节点距起始节点的距离满足 len_a - start_a == len_b - start_b。 所以第一个可能的公共节点距起始节点的距离是 len_a - len_b, 0。我们从这两个节点开始比较,直到找到第一个公共节点。 单向链表中,如何在给定节点前快速插入一个节点? 对于单向链表来说,在某个节点后面插入一个新节点是非常快的。 所以我们可以在给定节点后面插入一个新节点,然后交换给定节点和新节点的数据即可。 找到链表的倒数第m个节点 方法1: 首先遍历链表,统计链表的长度N。 然后再次遍历链表,找到第N-m+1个节点,即为倒数第m个节点。 方法2: 使用两个指针,并使它们指向的节点相距m-1个。 然后同时向前移动两个指针,当一个指针指最后一个节点时,第二个指针指向倒数第m个节点。 两个方法的复杂度都是O(n)。 但是当N较大而m较小时,方法2可能会更快一些。因为方法2能更好利用CPU的缓存。 更多阅读: http://baike

树和二叉树介绍

戏子无情 提交于 2020-02-28 17:56:56
树 树形结构 是数据元素(结点)之间有分支,并且具有层次关系的结构,可用于表示数据元素之间存在的一对多关系。 树(Tree) 是由n(n≥0)个结点构成的有限集合,当n=0时称为空树。若树非空,则具有以下两个性质: (1)有且仅有一个特定的结点,称为根(Root)。 (2)其余的结点可分为m个互不相交的集合T1,T2,…,Tm,其中每一个集合都是一棵树,并且称为根的子树( Subtree)。 如下图所示是有13个结点的树,A是根,其余结点分成三个互斥的集合T1={B,E,F,K,L}、T2={C,G}、T3={D,H,I,J,M},T1、T2、T3都是A的子树,其本身也是一棵树。 树形结构图 树的基本术语: 树结点( Tree Node) :树中一个独立单元。包含一个数据元素及若干指向其子树的分支,如上图中的A、B、C、D等。 树根(Root) :树中唯一没有前驱的结点,如上图中的A结点。 结点的度( Node Degree) :结点拥有的子树数,称为结点的度。例如,在上图中A的度为3,B的度为2,K的度为0。 树的度( Tree Degree) :树中各结点的度的最大值。如上图中树的度为3。 树叶(Leaf) :度为0的结点。例如,在图中,K、L、F、G、1、J、M都是树叶,也称叶结点。除根和叶子以外的其他结点称为中间结点。 双亲( Parent)和孩子( Child)

广度优先遍历和深度优先遍历

荒凉一梦 提交于 2020-02-28 14:40:35
1.BFS   广度优先搜索一层一层地进行遍历,每层遍历都是以上一层遍历的结果作为起点,遍历一个距离能访问到的所有节点。需要注意的是,遍历过的节点不能再次被遍历。 如上图所示: 第一层:   0 -> {6,2,1,5} 第二层:   6 -> {4}   2 -> {}   1 -> {}   5 -> {3} 第三层:   4 -> {}   3 -> {}   每一层遍历的节点都与根节点距离相同。设 di 表示第 i 个节点与根节点的距离,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 di <= dj。利用这个结论,可以求解最短路径等最优解问题:第一次遍历到目的节点,其所经过的路径为最短路径。应该注意的是,使用 BFS 只能求解无权图的最短路径,无权图是指从一个节点到另一个节点的代价都记为1。 在程序实现 BFS 时需要考虑以下问题: 1.队列:用来存储每一轮遍历得到的节点; 2.标记:对于遍历过的节点,应该将它标记,防止重复遍历。 2.DFS   广度优先搜索一层一层遍历,每一层得到的所有新节点,要用队列存储起来以备下一层遍历的时候再遍历。   而深度优先搜索在得到一个新节点时立即对新节点进行遍历:从节点 0 出发开始遍历,得到到新节点 6 时,立马对新节点 6 进行遍历,得到新节点 4;如此反复以这种方式遍历新节点,直到没有新节点了,此时返回。返回到根节点

LeetCode——39. 组合总和

瘦欲@ 提交于 2020-02-28 13:44:17
给定一个 无重复元素 的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。 说明: 所有数字(包括 target )都是正整数。 解集不能包含重复的组合。 示例 1: 输入: candidates = [2,3,6,7], target = 7, 所求解集为: [ [7], [2,2,3] ] 示例 2: 输入: candidates = [2,3,5], target = 8, 所求解集为: [ [2,2,2,2], [2,3,3], [3,5] ] 递归函数 这里我们新加入三个变量,start 记录当前的递归到的下标,out 为一个解,res 保存所有已经得到的解,每次调用新的递归函数时,此时的 target 要减去当前数组的的数,具体看代码如下: c++ class Solution { public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { vector<vector<int>> res; vector<int> out; combinationSumDFS(candidates, target, 0, out, res);

迭代器模式

泪湿孤枕 提交于 2020-02-28 11:32:31
迭代器模式 我们在日常的开发中,特别是在使用集合的过程中都或多或少使用了迭代器来对集合进行遍历。这时候我们就会思考一个问题,明明简单的For循环就能解决的集合遍历问题,我们非得创造一个迭代器来进行集合的遍历,使用迭代器来遍历到底有什么不一样的地方吗?本着‘存在即合理’的原则,我们通过手写迭代器的方式来深入了解一下迭代器模式的实现和带来的编码好处。 实现案例 有一个书架,我们想要知道这个书架里面堆了哪些书籍,这时候我们就需要对书架里面的书一本一本的遍历,直到没有书本,我们就能清楚的知道数据上堆满了哪些书籍。 可以被遍历的标记(生成迭代器的接口) 首先提供一个接口,来标明这个类是可以被遍历的集合。实现这个接口的类可以生成对应的迭代器。 123 public interface { public abstract Iterator iterator();} 迭代器接口 迭代器的抽象接口,定义了两个方法 (1)是否还有下一个元素 (2)返回下一个元素 1234 public interface Iterator{ public abstract boolean hasNext(); public abstract Object next();} 集合存储的元素(书本) 123 public class book{ private String name;} 迭代器实现类

107. 二叉树的层次遍历 II

允我心安 提交于 2020-02-28 10:46:03
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如: 给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其自底向上的层次遍历为: [ [15,7], [9,20], [3] ] 解题思路:首先temp临时记录层次遍历每一层的结点值,当遍历到下一层的结点时就将temp记录到result中. 代码实现 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int>> levelOrderBottom(TreeNode* root) { vector<vector<int> > result; //记录每一层的节点值 if(root == NULL) return result; queue<pair<TreeNode*,int> > Queue; vector<int> temp; /

【Golang】LeetCode-剑指Offer-面试题33-二叉搜索树的后序遍历序列【两种解法】

老子叫甜甜 提交于 2020-02-28 07:20:52
题目 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。 如果是则返回 true,否则返回 false。 假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树: 5 / \ 2 6 / \ 1 3 示例 1: 输入: [1,6,3,2,5] 输出: false 示例 2: 输入: [1,3,2,6,5] 输出: true 提示: 数组长度 <= 1000 解题思路 二叉搜索树 左子树的元素是都小于根元素,右子树都大于根元素 后序遍历 首先遍历左子树,然后遍历右子树,最后访问根结点,所以数组最后一个元素是根元素。 从前面开始遍历,小于的当前根元素的值是左子树的 当找到第一个大于当前根元素的值,可以确定后半段的元素都应是在当前节点的右子树 如果后半段(右子树)里面有小于根元素的值的元素,就说明这个不是二叉搜索树的后序遍历 最后循环校验每个子树是否也满足二叉搜索树的后序遍历即可。 解法一:非递归 –执行用时:0 ms --内存消耗:2.1 MB func verifyPostorder ( postorder [ ] int ) bool { if len ( postorder ) <= 2 { return true } //在二叉搜索树中,左子树的元素是都小于根元素,右子树都大于根元素 //在后序遍历中,最后一个元素是根元素 head := len (

List遍历方式

倾然丶 夕夏残阳落幕 提交于 2020-02-28 07:13:05
实现了RandomAccess接口的List,优先选择f普通for循环,其次foreach 未实现RandomAccess接口的List,优先选择iterator遍历(foreach底层也是用iterator来实现的),大的数据千万不要容普通for循环。 来源: oschina 链接: https://my.oschina.net/u/4434424/blog/3169115

数据结构——树

[亡魂溺海] 提交于 2020-02-27 22:43:34
数据结构——树 树其实就是不包含回路的连通无向图。 树的特性: 1)一棵树中的任意两个结点有且仅有唯一的一条路径连通; 2)一棵树如果有nn个结点,则它一定有n−1n−1条边; 3)在一棵树中加一条边将会构成一个回路。 树这种数据结构的用途: 例如:家族的族谱图、公司的组织结构图、书的目录等。 1. 二叉树 二叉树是一种特殊的树。二叉树的特点是每个结点最多有两个儿子。 二叉树用范围最广。一颗多叉树也可以转化为二叉树。 1) 满二叉树 :二叉树中每个内部节点都有两个儿子。满二叉树所有的叶节点都有相同的深度。 满二叉树是一棵深度为h且有2h−12h−1个结点的二叉树。 2) 完全二叉树 :若设二叉树的高度为hh,除了第hh层外,其他层的结点数都达到最大个数,第h层从右向左连续 缺若干个结点,则为完全二叉树。 特点: 由上图发现: 1)如果一棵完全二叉树的父节点编号为KK,则其左儿子的编号是2K2K,右儿子的结点编号为2K+12K+1, 公式总结: 2)已知完全二叉树的总节点数为n求叶子节点个数: 当n为奇数时:(n+1)/2 当n为偶数时 : (n)/2 3)已知完全二叉树的总节点数为n求父节点个数:为:n/2 4)已知完全二叉树的总节点数为n求叶子节点为2的父节点个数: 当n为奇数时:n/2 当n为偶数时 : n/2-1 5)如果一棵完全二叉树有N个结点,那么这棵二叉树的深度为

DSA学习笔记——二叉树之遍历(先序遍历)

和自甴很熟 提交于 2020-02-27 18:57:04
1、递归版 template <typename T, typename VST> void travPre_R(BinNode<T>* x, VST& visit){ if(!x) return; visit(x->data); travPre_R(x->lc, visit); travPre_R(x->rc, visit); } 2、迭代版 template <typename T, typename VST> static void visitAlongLeftBranch(BinNode<T>* x, VST& visit, Stack<BinNode<T>*>& S){ while(x){ visit(x->data); S.push(x->rc); x = x->lc; } } //先序遍历迭代版版本2代码 template <typename T, typename VST> void travPre_I2(BinNode<T>* x, VST& visit){ Stack<BinNode<T>*> S; while(true){ visitAlongLeftBranch(x, visit, S); if(S.empty()) break; x = S.pop(); } } 来源: CSDN 作者: Xiaaaaaacy 链接: https://blog.csdn