《程序员代码面试指南》第一章 栈和队列 构造数组的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 树中是否有与 ...
随机推荐
- 微信小程序登录JAVA后台
代码地址如下:http://www.demodashi.com/demo/12736.html 登录流程时序登录流程时序 具体的登录说明查看 小程序官方API 项目的结构图: springboot项目 ...
- 链表的艺术——Linux内核链表分析
引言: 链表是数据结构中的重要成员之中的一个.因为其结构简单且动态插入.删除节点用时少的长处,链表在开发中的应用场景许多.仅次于数组(越简单应用越广). 可是.正如其长处一样,链表的缺点也是显而易见的 ...
- javascript 温故而知新 getBoundingClientRect
getBoundingClientRect获取元素位置 getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置. getBoundingClient ...
- php给图片添加文字水印方法汇总
在php中要给图片加水印我们需要给php安装GD库了,这里我们不介绍GD库安装,只介绍怎么利用php给图片添加文字水印的4种方法的汇总.有需要的小伙伴可以参考下. 1: 面向过程的编写方法 1 2 3 ...
- iOS swift objc_setAssociatedObject和objc_getAssociatedObject使用
oc中的AssociationsManager在swift中也是可以实现的 使用方法请看下面一个例子 import UIKit extension UIButton { func fk_addActi ...
- selenium驱动Firefox跳转页慢慢慢的问题(待验证)
转载至http://www.cnblogs.com/yicaifeitian/p/5198871.html 为了解决这个问题,我是查了很多资料,解决方案是百度出来的.抱歉,我忘记出处在哪了,代码如下: ...
- 多媒体开发之视频格式---1080p逐行和1080i隔行
(1)简介 (2)1080p和1080i的区别 (3) ------------------autho:pkf ----------------------time:2015-1-4 (1)简介 (2 ...
- 8168开发之---1g内存换成512M的内存映射配置
最近在帮新来同事调式内存分配,起初是将config.bld 中的内存在标配的基础上减少sr1,和tiler 将dsp从9m增加到16m,然后编译通过, 可是在加载的时候卡住了,init.sh 过,lo ...
- HDOJ 4923 Room and Moor
用一个栈维护b的值,每次把一个数放到栈顶. 看栈首的值是不是大于这个数,假设大于的话将栈顶2个元素合并.b的值就是这两个栈顶元素的平均值. .. Room and Moor Time Limit: 1 ...
- vue2 本地安装