遍历

114. Flatten Binary Tree to Linked List(Medium)

邮差的信 提交于 2020-01-19 09:16:33
这题需要找到规律:前序遍历 第一想法是新建一个TreeNode t,在前序遍历root的同时,不断在t的右节点新建。此方法确实可行,但是原题返回是void空,说明只能在原结构上操作。 正确解法: 既然iterative的方法不行,那么就试试recursive。 因为recursive是反的,所以遍历顺序为right, left, root,从最右边开始建,运用临时变量TreeNode pre指向之前的节点,然后root.right = pre,递归直到原始root class Solution { TreeNode pre = null; public void flatten(TreeNode root) { if(root == null) return; flatten(root.right); flatten(root.left); root.right = pre; root.left = null; pre = root; } } 来源: https://www.cnblogs.com/zzb666/p/12210916.html

递归 || 递归的相关实例练习

拈花ヽ惹草 提交于 2020-01-19 07:02:44
递归的使用前提: 当调用方法的时候,方法的主体不变,每次调用方法的参数不同,可以使用递归 package com.itheima.demo02.Recursion; public class Demo01Recurison { public static void main(String[] args) { //a(); b(1); } /* 构造方法,禁止递归 编译报错:构造方法是创建对象使用的,一直递归会导致内存中有无数多个对象,直接编译报错 */ public Demo01Recurison() { //Demo01Recurison(); } /* 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。 11157 Exception in thread "main" java.lang.StackOverflowError */ private static void b(int i) { System.out.println(i); if(i==20000){ return; //结束方法 } b(++i); } /* 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。 Exception in thread "main" java.lang.StackOverflowError */ private static void a() {

合并两个有序数组

寵の児 提交于 2020-01-18 21:55:48
题目: 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。 说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。 方法一: 将两个数组合并之后再排序。 class Solution { public void merge ( int [ ] nums1 , int m , int [ ] nums2 , int n ) { System . arraycopy ( nums2 , 0 , nums1 , m , n ) ; Arrays . sort ( nums1 ) ; } } 方法二: 双指针从后向前数组遍历 因为 nums1 的空间都集中在后面,所以从后向前处理排序的数据会更好,节省空间,一边遍历一边将值填充进去 设置指针flag1 和 flag2 分别指向 nums1 和 nums2 的有数字尾部,从尾部值开始比较遍历,同时设置指针 flag 指向 nums1 的最末尾,每次遍历比较值大小之后,则进行填充 当 flag1<0 时遍历结束,此时 nums2 中还有数据未拷贝完全,将其直接拷贝到 nums1 的前面,最后得到结果数组 class Solution { public

Java设计模式详解-迭代器模式

你说的曾经没有我的故事 提交于 2020-01-18 18:55:29
1 概念 1.1 定义 提供一种方法,顺序访问同一集合对象中的各个元素,而又不暴露该对象的内部表示 1.2 类型 行为型 迭代器模式(Iterator Pattern) 目前已经是一个没落的模式,基本上没人会单独写一个迭代器,除非是产品性质的开发,其定义如下: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。) 迭代器是为容器(能容纳对象的所有类型都可以称之为容器,例如Collection、Set等)服务的,迭代器模式就是为解决遍历这些容器中的元素而诞生的 1.3 通用类图 迭代器模式提供了遍历容器的方便性,容器只要管理增减元素就可以了,需要遍历时交由迭代器执行 1.4 角色 Iterator抽象迭代器 抽象迭代器负责定义访问和遍历元素的接口,而且基本上是有固定的3个方法: first()获得第一个元素 next()访问下一个元素 hasNext()是否已经访问到底部 ConcreteIterator具体迭代器 具体迭代器角色要实现迭代器接口,完成容器元素的遍历。 Aggregate抽象容器

递归与非递归及其相互转换

蓝咒 提交于 2020-01-18 15:48:13
一、什么是递归 递归是指某个函数直接或间接的调用自身。问题的求解过程就是划分成许多相同性质的子问题的求解,而小问题的求解过程可以很容易的求出,这些子问题的解就构成里原问题的解了。 二、递归的几个特点 1. 递归式,就是如何将原问题划分成子问题。 2. 递归出口,递归终止的条件,即最小子问题的求解,可以允许多个出口。 3. 界函数,问题规模变化的函数,它保证递归的规模向出口条件靠拢 三、递归的运做机制 很明显,很多问题本身固有的性质就决定此类问题是递归定义,所以递归程序很直接算法程序结构清晰、思路明了。但是递归的执行过程却很让人费解,这也是让很多人难理解递归的原因之一。由于递归调用是对函数自身的调用,在一次调用没有结束之前又开始了另外一次调用, 按照作用域的规定,函数在执行终止之前是不能收回所占用的空间,必须保存下来,这也就意味着每一次的调用都要把分配的相应空间保存起来。 为了更好管理这些空间,系统内部设置一个栈,用于存放每次函数调用与返回所需的各种数据, 其中主要包括函数的调用结束的返回地址,返回值,参数和局部变量等。 其过程大致如下: 1. 计算当前函数的实参的值 2. 分配空间,并将首地址压栈,保护现场 3. 转到函数体,执行各语句,此前部分会重复发生(递归调用) 4. 直到出口,从栈顶取出相应数据,包括,返回地址,返回值等等 5. 收回空间,恢复现场

js数组两层遍历

心已入冬 提交于 2020-01-18 09:42:42
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>element-ui</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <script src="https://unpkg.com/element-ui/lib/index.js"></script> </head> <body> <div id="app"> </div> <script> new Vue({ el: "#app", data: { unlockType: [{ code: "A", name1: "APP开门" }, { code: "F", name1: "人脸识别" }, {

二叉搜索树,B树,B+树,索引

痴心易碎 提交于 2020-01-18 05:06:23
mongodb的默认存储引擎WiredTiger使用了B树索引 mysql的默认存储引擎InnoDB索引使用了B+树实现,那么各自为什么这样实现呢? 二叉搜索树 如上图是一个简单的二叉搜索树,是最为大家熟知的一种数据结构,它为什么不适合用作数据库索引? (1)当数据量大的时候,树的高度会比较高,数据量大的时候,查询会比较慢 (2)每个节点只存储一个记录,可能导致一次查询有很多次磁盘IO B树 B树的特点是: (1)不再是单纯的二叉而是m叉 (2)叶子节点,非叶子节点,都存储数据 (3)中序遍历,可以获得所有节点 (4) 非根节点包含的关键字个数j满足, (┌m/2┐)-1 <= j <= m-1 ,节点分裂时要满足这个条件。 B+树 B+树,如上图,仍是m叉搜索树,在B树的基础上,做了一些改进: (1)非叶子节点不再存储数据,数据只存储在同一层的叶子节点上;B+树种 根到每一个节点的路径长度一样,而B树不是这样 (2)叶子之间,增加了链表,获取所有节点,不再需要中序遍历 这些改进让B+树比B树有更优的特性: (1)范围查找,定位min与max之后,中间叶子节点,就是结果集,不用中序回溯;范围查询在SQL中用得多,这是B+树比B树最大的优势。 (2)叶子节点存储实际记录行,记录行相对比较紧密的存储,适合大数据量磁盘存储;非叶子节点存储记录的PK,用于查询加锁,适合内存存储。 (3

小白之路由浅入深之------day16

人盡茶涼 提交于 2020-01-18 04:24:12
目录 1.Map集合 1.1Map集合概述和特点【理解】 1.2Map集合的基本功能【应用】 1.3Map集合的获取功能【应用】 1.4Map集合的遍历(方式1)【应用】 1.5Map集合的遍历(方式2)【应用】 1.6Map集合的案例【应用】 1.6.1HashMap集合练习之键是String值是Student 1.6.2HashMap集合练习之键是Student值是String 1.6.3集合嵌套之ArrayList嵌套HashMap 1.6.4集合嵌套之HashMap嵌套ArrayList 1.6.5统计字符串中每个字符出现的次数 2.Collections集合工具类 2.1Collections概述和使用【应用】 2.2ArrayList集合存储学生并排序【应用】 3.斗地主案例 3.1模拟斗地主案例-普通版本【应用】 3.2模拟斗地主案例-升级版本【应用】 1.Map集合 1.1Map集合概述和特点【理解】 Map集合概述 interface Map < K , V > K:键的类型;V:值的类型 Map集合的特点 键值对映射关系 一个键对应一个值 键不能重复,值可以重复 元素存取无序 Map集合的基本使用 public class MapDemo01 { public static void main ( String [ ] args ) { //创建集合对象 Map

如何将类数组转换为真正的数组

蹲街弑〆低调 提交于 2020-01-18 02:09:53
一、遍历类数组,依次将元素放入一个空数组。 类数组本身虽然不是数组,但是有interator接口,所以可遍历。(interator指可遍历、可迭代) 例如: 页面有三个div,divEle是一个nodeList,即元素集合,并非纯数组。可以用let of遍历。然后依次放入一个空数组。这样divArr就是div元素集合的数组。 二、用扩展运算符或者Array.from()方法转换 es6新增了扩展运算符(…)以及Array.from()方法,可以直接将类数组转换为真正的数组。 扩展运算符的使用前提,是对象有Interator接口,这和let of的前提是一样的。但是用扩展运算符和Array.from()无疑简洁很多。 需要特别指出的是,Array.from()方法可以将任意具有length属性的对象转换成真正的数组(类数组有length属性)。具体转换形式可参考阮一峰老师的《es6标准入门》一书。 三、利用apply展开 apply方法的第二个参数是数组,也可以是类数组,在调用的时候会将第二个参数依次展开。 过程类似扩展运算符。 以上三种方法推荐扩展运算符,方式非常的简洁。 来源: CSDN 作者: 陈红光 链接: https://blog.csdn.net/weixin_42924048/article/details/103934493

剑指offer37:序列化二叉树

限于喜欢 提交于 2020-01-17 23:55:17
一 题目:序列化二叉树 二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#)。 二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。 二 思路分析 1 序列化 可以使用前序遍历来将节点保存到字符串中,但是为了反序列化,需要以满二叉树的方式保存,那么没有的地方我们就用"#"来表示! 分为多种情况, 情形一:该节点没有子节点 此时,返回的字符串为:“节点的value, #, #” 情形二:该节点只有一个左子节点 返回的字符串为:“节点的value,节点的左子节点的value, #” 情形三:该节点只有一个右子节点 返回的字符串为:“节点的value,#, 节点的右子节点的value” 递归的方法。不用去追究每次递归的细节,只需要关注总问题和子问题之间的关系即可。如下代码所示内容,因为不管是总问题还是子问题,都需要将结果保存到字符串中,那么这里就巧妙的使用了StringBuilder(),将子问题遍历的结果保存到字符串中,然后再使用StringBuilder的ad方法,添加到总问题中。就是这样简单! 代码如下: public String Serialize (