《程序员代码面试指南》第一章 栈和队列 构造数组的MaxTree
题目
给出一个无重复元素的数组,构造此数组的MaxTree,
java代码
/**
* @Description: 构造数组的MaxTree
* @Author: lizhouwei
* @CreateDate: 2018/4/5 22:16
* @Modify by:
* @ModifyDate:
*/
public class Chapter1_8 {
public Node getMaxTree(int[] arr) {
if (arr == null) {
return null;
}
int length = arr.length;
Node[] nodes = new Node[length];
//初始化Node数组
for (int i = 0; i < length; i++) {
nodes[i] = new Node(arr[i]);
}
//存放当前节点往左 第一个大于当前节点的节点
Map<Node, Node> leftMap = new HashMap<Node, Node>();
//存放当前节点往右 第一个大于当前节点的节点
Map<Node, Node> rightMap = new HashMap<Node, Node>();
//存放遍历到节点
Stack<Node> stack = new Stack<Node>();
for (int i = 0; i < length; i++) {
//关键地方,判断栈顶元素的值是否小于当前元素的值,如果小于则在map中记录栈顶元素的往左数第一个元素
while (!stack.isEmpty() && stack.peek().value < nodes[i].value) {
popStackToMap(stack, leftMap);
}
//存放当前元素,前提保证栈中没有比小的元素
stack.push(nodes[i]);
}
//如果栈中还有元素,则循环获取栈中元素的往左数第一个大于他的元素
while (!stack.isEmpty()) {
popStackToMap(stack, leftMap);
}
for (int i = length - 1; i >= 0; i--) {
//关键地方,判断栈顶元素的值是否小于当前元素的值,如果小于则在map中记录栈顶元素的往右数第一个元素
while (!stack.isEmpty() && stack.peek().value < nodes[i].value) {
popStackToMap(stack, rightMap);
}
//存放当前元素,前提保证栈中没有比小的元素
stack.push(nodes[i]);
}
//如果栈中还有元素,则循环获取栈中元素的往右数第一个大于他的元素
while (!stack.isEmpty()) {
popStackToMap(stack, rightMap);
}
//再将 每个元素 左右 最大的元找见后,开始构造MaxTree
Node head = null;
for (int i = 0; i < length; i++) {
Node node = nodes[i];
Node leftNode = leftMap.get(node);
Node rightNode = rightMap.get(node);
//左右最大的元素都为空,则此元素是数组中最大,作为根节点
if (leftNode == null && rightNode == null) {
head = node;
} else if (leftNode == null) {
if (rightNode.left == null) {
rightNode.left = node;
} else {
rightNode.right = node;
}
} else if (rightNode == null) {
if (leftNode.left == null) {
leftNode.left = node;
} else {
leftNode.right = node;
}
} else {
Node parent = leftNode.value < rightNode.value ? leftNode : rightNode;
if (parent.left == null) {
parent.left = node;
} else {
parent.right = node;
}
}
}
return head;
}
public void popStackToMap(Stack<Node> stack, Map<Node, Node> map) {
Node node = stack.pop();
if (stack.isEmpty()) {
map.put(node, null);
} else {
map.put(node, stack.peek());
}
}
//简单的用递归中序遍历一下生成的MaxTree
public void recInOrder(Node head) {
if (head == null) {
return;
}
recInOrder(head.left);
System.out.print(head.value + " ");
recInOrder(head.right);
}
//测试
public static void main(String[] args) {
Chapter1_8 chapter = new Chapter1_8();
int[] arr = {3, 4, 5, 1, 2};
Node head = chapter.getMaxTree(arr);
chapter.recInOrder(head);
}
}
class Node {
public int value;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
}
《程序员代码面试指南》第一章 栈和队列 构造数组的MaxTree的更多相关文章
- 程序员代码面试指南 IT名企算法与数据结构题目最优解
原文链接 这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮 ...
- 程序员代码面试指南:IT名企算法与数据结构题目最优解
第1章栈和队列 1设计一个有getMin功能的栈(士★☆☆☆) 1由两个栈组成的队列(尉★★☆☆) 5如何仅用递归函数和栈操作逆序一个栈(尉★★☆☆) 8猫狗队列(士★☆☆☆)10用一个栈实现另一 ...
- 《程序员代码面试指南》第八章 数组和矩阵问题 打印N 个数组整体最大的Top K
题目 打印N 个数组整体最大的Top K java代码 package com.lizhouwei.chapter8; /** * @Description: 打印N 个数组整体最大的Top K * ...
- 《程序员代码面试指南》第一章 栈和队列 设计一个有getMin功能的栈
题目 实现一个特殊的栈,在实现栈的基本功能上,再实现返回栈中最小的元素的操作 要求 1. pop.push.getMin操作时间复杂度都是O(1) 2. 设计的栈类型可以使用现成的栈结构 java代码 ...
- 《程序员代码面试指南》第一章 栈和队列 最大值减去最小值小于或等于num的数量
题目 给定整数数组arr和整数num,共返回多少的数组满足如下情况 max(arr[i...j]) - min(arr[i...j]) <= num max(arr[i...j])表示数组arr ...
- 左神算法书籍《程序员代码面试指南》——1_01设计一个有getMin功能的栈
[题目] 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. [要求] 1.pop.push.getMin操作的时间复杂度都是O(1).2.设计的栈类型可以使用现成的栈结构. ...
- 《程序员代码面试指南》第五章 字符串问题 去掉字符串中连续出现k 个0 的子串
题目 去掉字符串中连续出现k 个0 的子串 java代码 package com.lizhouwei.chapter5; /** * @Description: 去掉字符串中连续出现k 个0 的子串 ...
- 《程序员代码面试指南》第三章 二叉树问题 Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题
题目待续.... Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题 java代码
- 《程序员代码面试指南》第三章 二叉树问题 判断t1 树中是否有与t2 树拓扑结构完全相同的子树
题目 判断t1 树中是否有与t2 树拓扑结构完全相同的子树 java代码 package com.lizhouwei.chapter3; /** * @Description: 判断t1 树中是否有与 ...
随机推荐
- 在eclipse中使用Maven建web工程的两种方式
Eclipse版本:Neon Release (4.6.0) Maven版本:3.3.9 第一种方式: 右键新建maven工程,勾选创建一个简单工程 填入信息,注意打包方式要改为war 点击完成,创建 ...
- (十)Thymeleaf用法——Themeleaf内联
5. 内联 [[...]]是内联文本的表示格式,但需要使用th:inline属性(分为text,javascript,none)激活. 5.1 文本内联 <p th:inline=&quo ...
- Android中database所在文件夹路径(9.6)
1 sd----->data---->对应app---->databases----->创建的db 2 push到pc上,可以使用GUI工具SQLiteSpy直接查看datab ...
- Android适配方案小结(二)
该节主要记录从代码中获取与屏幕适配相关的各个參数: Java代码例如以下 public class ScreenUtil { /** * Note: * 仅仅有activity能够使用getWindo ...
- 用VS2010创建三层架构开发模式及三层架构的研究
三层架构的研究 三层体系结构的概念 用户界面表示层(USL) 业务逻辑层(BLL) 数据访问层(DAL) BLL将USL与DAL隔开了,并且加入了业务规则 各层的作用 1:数据数据访问层:主要是对 ...
- 使用React的static方法实现同构以及同构的常见问题
代码地址请在github查看,假设有新内容.我会定时更新.也欢迎您star,issue,共同进步 1.我们服务端渲染数据从何而来 1.1 怎样写出同构的组件 服务端生成HTML结构有时候并不完好.有时 ...
- json格式转数组注意事项
今天遇到一个特别奇葩的问题,json格式明明是正确的,转数组时却就是出不来,后来才发现是文件的编码问题,文件的编码一定要是utf-8无BOM格式,这点一定要切记!切记! 如果想确认json是否正确:h ...
- TortoiseSVN与VisualSVN Server搭建SVN版本控制系统(转)
地址:http://www.cnblogs.com/xing901022/p/4399382.html
- Lumen开发:结合Redis实现消息队列(1)
1.简介 Lumen队列服务为各种不同的后台队列提供了统一的API.队列允许你推迟耗时任务(例如发送邮件)的执行,从而大幅提高web请求速度. 1.1 配置 .env文件的QUEUE_DRIVER选项 ...
- 七. PHP模式设计----运行及描写叙述任务
1. 解析器模式 //解析器内容类 //用于存放表达式的运算结果,并且能依据传入的表达式返回当初记录的结果 class InterpreterContext{ private $expressions ...