链接:https://www.nowcoder.com/questionTerminal/a502c7c3c65e41fdaf65eec9e0654dcb

来源:牛客网


[编程题]构造MaxTree


对于一个没有重复元素的整数数组,请用其中元素构造一棵MaxTree,MaxTree定义为一棵二叉树,其中的节点与数组元素一一对应,同时对于MaxTree的每棵子树,它的根的元素值为子树的最大值。现有一建树方法,对于数组中的每个元素,其在树中的父亲为数组中它左边比它大的第一个数和右边比它大的第一个数中更小的一个。若两边都不存在比它大的数,那么它就是树根。请证明这个方法的正确性,同时设计O(n)的算法实现这个方法。

给定一个无重复元素的数组A和它的大小n,请返回一个数组,其中每个元素为原数组中对应位置元素在树中的父亲节点的编号,若为根则值为-1。


测试样例:

[3,1,4,2],4

返回:[2,0,-1,2]


算法如下:

对于每个节点,寻找左右两个第一个大于它的数,选择其中的较小点作为父亲节点

现在需要证明

  1. 每个点最多只有两个子节点

    利用反证法,假设节点i的某一侧有两个儿子节点,设为k1,k2。

    因为数组中不存在重复元素,所以可以假设\(k1<k2\),那么根据算法,k1会以k2为父节点,于假设不符

    k1>k2的话,k2根本就不会找到i,同样不符。

    因此得证
  2. 最后形成的是一颗树

    除了根节点,所有节点的都会有一个比它大的父节点,由于根节点是数组中最大的节点,那么所有的

    节点最终都会指向根节点。

最后为了寻找相邻最大数,使用单调栈算法即可,关于单调栈的设计和证明:http://www.cnblogs.com/zsyacm666666/p/6812896.html

public int[] buildMaxTree(int[] A, int n) {
// write code here
int ans[]=new int[A.length];
int lb[]=new int[A.length];
int rb[]=new int[A.length];
Arrays.fill(lb,-1);Arrays.fill(rb,-1);
Stack<Integer>stack=new Stack<>();
for(int i=0;i<A.length;i++) {
while(!stack.empty()&&A[stack.peek()]<A[i]) {
stack.pop();
}
if(!stack.empty()) lb[i]=stack.peek();
stack.push(i);
}
while(!stack.empty()) stack.pop();
for(int i=A.length-1;i>=0;i--) {
while(!stack.empty()&&A[stack.peek()]<A[i]) {
stack.pop();
}
if(!stack.empty()) rb[i]=stack.peek();
stack.push(i);
}
for(int i=0;i<A.length;i++) {
if(lb[i]==-1&&rb[i]==-1) ans[i]=-1;
else if(lb[i]==-1) ans[i]=rb[i];
else if(rb[i]==-1) ans[i]=lb[i];
else ans[i]=(A[lb[i]]<A[rb[i]]?lb[i]:rb[i]);
}
return ans;
}

构造MaxTree的更多相关文章

  1. (算法)构造MaxTree

    题目: 给定一个没有重复元素的数组A,定义A上的MaxTree如下:MaxTree的根节点为A中最大的数,根节点的左子树为数组中最大数左边部分的MaxTree,右子树为数组中最大数右边部分的MaxTr ...

  2. 《程序员代码面试指南》第一章 栈和队列 构造数组的MaxTree

    题目 给出一个无重复元素的数组,构造此数组的MaxTree, java代码 /** * @Description: 构造数组的MaxTree * @Author: lizhouwei * @Creat ...

  3. 构造数组的MaxTree

    题目 一个数组的MaxTree定义: 数组必须没有重复元素 MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点 包括MaxTree树在内且在其中的每一棵子树上,值最大的节点都是树的头 给定一 ...

  4. 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序

    接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...

  5. 左神算法进阶班3_1构造数组的MaxTree

    题目 一个数组的MaxTree定义: 数组必须没有重复元素 MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点 包括MaxTree树在内且在其中的每一棵子树上,值最大的节点都是树的头 给定一 ...

  6. 算法总结之 构造数组MaxTree

    一个数组的MaxTree定义如下: 数组必须没有重复元素 MaxTree是一颗二叉树,数组的每一个值对应一个二叉树的节点 包括MaxTre树在内且在其中的每一颗子树上,值最大的节点都是树的头 给定一个 ...

  7. 左神算法书籍《程序员代码面试指南》——1_08构造数组的MaxTree

    [题目] 将一个没有重复数字的数组中的数据构造一个二叉树 每个节点都是该子树的最大值 [要求] 时间复杂度为O(N)[题解] 使用单调栈,栈的顺序是维持从大到小排序 通过使用单调栈,将数组中中所有数的 ...

  8. 学习笔记:Maven构造版本号的方法解决浏览器缓存问题

    需要解决的问题 在做WEB系统开发时,为了提高性能会利用浏览器的缓存功能,其实即使不显式的申明缓存,现代的浏览器都会对静态文件(js.css.图片之类)缓存.但也正因为这个问题导致一个问题,就是资源的 ...

  9. 一步步构造自己的vue2.0+webpack环境

    前面vue2.0和webpack都已经有接触了些(vue.js入门,webpack入门之简单例子跑起来),现在开始学习如何构造自己的vue2.0+webpack环境. 1.首先新建一个目录vue-wk ...

随机推荐

  1. Chef and Graph Queries CodeChef - GERALD07

    https://vjudge.net/problem/CodeChef-GERALD07 可以用莫队+带撤销并查集做 错误记录: 1.调试时数组开小了,忘了改大就交了 2.88行和91行少了备份num ...

  2. UVa 1220 Party at Hali-Bula 晚会

    #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #i ...

  3. 简单了解Linux中 du 和 df 以及它们的区别

    一 .du : 显示每个文件和目录的磁盘使用空间~~~文件的大小. 命令参数: -a   #显示目录中文件的大小  单位 KB . -b  #显示目录中文件的大小,以字节byte为单位. -c  #显 ...

  4. Centos 6.5安装MySQL-Python遇到的问题--解决办法一

    系统:CentOS release 6.5 (Final) MySQL版本:mysql  Ver 14.14 Distrib 5.7.19, for Linux (x86_64) using  Edi ...

  5. 如何正确从他人机器MySQL数据库下拷贝出.sql,再导入到自己windows下MySQL数据库(图文详解)

    不多说,直接上干货! 我这里,是放在桌面上. 登陆数据库 然后, mysql -uroot -p 默认是回车. 创建数据库 CREATE DATABASE securityonion_db; 目的,就 ...

  6. C#实现为类和函数代码自动添加版权注释信息的方法

    这篇文章主要介绍了C#实现为类和函数代码自动添加版权注释信息的方法,主要涉及安装文件的修改及函数注释模板的修改,需要的朋友可以参考下   本文实例讲述了C#实现为类和函数代码自动添加版权注释信息的方法 ...

  7. AJPFX关于Swing组件的总结

    默认布局管理器是流式布局(FlowLayout) 按钮的建立: jb1=new JButton("香蕉") 面板的建立:jp1=new JPanel(); 设置JFrame的标题: ...

  8. CAS分析

    CAS:Compare and Swap, 翻译成比较并交换.   CAS 指的是现代 CPU 广泛支持的一种对内存中的共享数据进行操作的一种特殊指令.这个指令会对内存中的共享数据做原子的读写操作.简 ...

  9. CF983A Finite or not?

    思路: 如果p,q不互质,先把q除以p,q的最大公约数.接下来只要b中包含了所有q的质因子就可以了.可以在gcd(q, b) 不等于1的时候不断地用q除以gcd(q, b).最后如果q等于1,说明Fi ...

  10. poj3280 Cheapest Palindrome

    思路: 区间dp.添加和删除本质相同. 实现: #include <iostream> #include <cstdio> using namespace std; int n ...