力扣(leetcode)每日一题 699 掉落的方块 | 线段树|经典

699. 掉落的方块

题干

在二维平面上的 x 轴上,放置着一些方块。
给你一个二维整数数组 positions ,其中 positions[i] = [lefti, sideLengthi] 表示:第 i 个方块边长为 sideLengthi ,其左侧边与 x 轴上坐标点 lefti 对齐。
每个方块都从一个比目前所有的落地方块更高的高度掉落而下。方块沿 y 轴负方向下落,直到着陆到 另一个正方形的顶边 或者是 x 轴上 。一个方块仅仅是擦过另一个方块的左侧边或右侧边不算着陆。一旦着陆,它就会固定在原地,无法移动。
在每个方块掉落后,你必须记录目前所有已经落稳的 方块堆叠的最高高度 。
返回一个整数数组 ans ,其中 ans[i] 表示在第 i 块方块掉落后堆叠的最高高度。

题解

这个题目不仅需要用线段树,在进行线段树初始化的时候还有一个非常重要的技巧

class Solution {

    public static List<Integer> fallingSquares(int[][] positions) {
        TreeSet<Integer> treeSet = new TreeSet<>();
        for (int[] position : positions) {
            treeSet.add(position[0]);
            treeSet.add(position[0] + position[1] - 1);
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        int count = 1;
        for (Integer i : treeSet) {
            map.put(i, count);
            count++;
        }
        SegmentTree segmentTree = new SegmentTree(map.size());
        segmentTree.build(positions, map);
        return segmentTree.getResult();

    }

    // 位置1 位置2   遍历位置  数量累加?

    public static class SegmentTree {
        int root = 1;
        int left = 1;
        int right;
        int[] maxArr;
        int[] updateArr; // 反正不会更新为0
        List<Integer> collect = new ArrayList<>();

        public SegmentTree(int n) {
            int length = n + 1;
            right = n;
            maxArr = new int[length * 4];
            updateArr = new int[length * 4];
        }

        public void update(int start, int end, int value) {
            update(start, end, value, left, right, root);
        }

        public void update(int start, int end, int value, int left, int right, int node) {
            if (start <= left && right <= end) {
                updateArr[node] = value;
                maxArr[node] = value;
                return;
            }
            int mid = (left + right) / 2;
            if (start <= mid) {
                update(start, end, value, left, mid, node * 2);
            }
            if (mid < end) {
                update(start, end, value, mid + 1, right, node * 2 + 1);
            }
            maxArr[node] = Math.max(maxArr[node * 2], maxArr[node * 2 + 1]);
        }

        public int getMax(int start, int end) {
            return getMax(start, end, left, right, root);
        }

        public int getMax(int start, int end, int left, int right, int node) {
            if (start <= left && right <= end) {
                return maxArr[node];
            }
            int mid = (left + right) / 2;
            int max = 0;
            int max2 = 0;
            // 刷新
            if (updateArr[node] != 0) {// 下发任务
                updateArr[node * 2] = updateArr[node];
                updateArr[node * 2 + 1] = updateArr[node];
                maxArr[node * 2] = updateArr[node];
                maxArr[node * 2 + 1] = updateArr[node];
                updateArr[node] = 0;
            }
            if (start <= mid) {
                max = getMax(start, end, left, mid, node * 2);
            }
            if (mid < end) {
                max2 = getMax(start, end, mid + 1, right, node * 2 + 1);
            }
            return Math.max(max, max2);
        }

        int curMax = 0;

        public void build(int[][] positions, HashMap<Integer, Integer> map) {
            for (int[] position : positions) {
                int i1 = position[0]; // 2,2      2,3 算头不算尾
                int i2 = position[1];
                Integer index1 = map.get(i1);
                Integer index2 = map.get(i1 + i2 - 1);
                // 获取范围上的最大值
                int max = getMax(index1, index2); // 范围 i1, i1 + i2
                update(index1, index2, max + i2);
                curMax = Math.max(curMax, max + i2);
                collect.add(curMax);
            }
        }

        public List<Integer> getResult() {
            return collect;
        }
    }

}
总结

还是去网上找视频看把,这个真不好解释

首先正放心 4,6 会落在4,6和10,6的位置,但是10,6的位置是没有支点的,也就是用不了的。因为这时候10位置来了方块,是无法累加上去的
然后这里不能记录4,6 5,6 6,6 7,6 8,6 9,6 这里需要对点进行map的压缩。
这样只要头尾的点就可以了。
也就是你会有很多点 数值很大 100,10000,555555,666666,666669
但是会通过hash映射到 1,2,3,4,5上。非常的紧凑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/885423.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决 Android WebView 无法加载 H5 页面常见问题的实用指南

目录 1. WebView 简介 2. 常见问题 3. 网络权限设置 4. 启用 JavaScript 5. DOM Storage 的重要性 6. 处理 HTTPS 问题 7. 设置 WebViewClient 8. 调试工具 9. 其他调试技巧 10. 结论 相关推荐 1. WebView 简介 Android WebView 是一种视图组件&#xff0c;使得 And…

LiveGBS流媒体平台GB/T28181功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大

LiveGBS流媒体平台GB/T28181功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大 1、直播播放2、录像播放3、搭建GB28181视频直播平台 1、直播播放 国标设备-》查看通道-》播放 &#xff0c;左键单击可以拉取矩形框&#xff0c;放大选中的范围&#xff0c;释…

vue-element 表格组合查询 - fc-table-search 组件封装

开发目的 解决搜索form参数读取&#xff0c;配合异步请求&#xff0c;更新渲染数据&#xff1b;支持自适应高度&#xff0c;分页查询&#xff0c;搜索查询/重置。 额外提供formater类型&#xff1a;标签定义&#xff0c;金额&#xff0c;时间格式化&#xff0c;跨页勾选&#x…

uniapp/vue项目 import 导入文件时提示Module is not installed,‘@/views/xxx‘路径无法追踪

文章目录 背景解决方案1.IDE配置2.alias&#xff08;别名&#xff09;配置webpackvue-clivite 3.检查 jsconfig.json 或 tsconfig.json 写在最后 前往闪闪の小窝以获得更好的阅读和评论体验 背景 Vue3在我自学Vue的时候看过一点&#xff0c;实操过一点&#xff0c;但是太久没用…

基于php的酒店管理系

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

动手学深度学习(李沐)PyTorch 第 3 章 线性神经网络

3.1 线性回归 线性回归是对n维输入的加权&#xff0c;外加偏差 线性回归可以看作是单层神经网络 回归问题中最常用的损失函数是平方误差函数。 平方误差可以定义为以下公式&#xff1a; 常数1/2不会带来本质的差别&#xff0c;但这样在形式上稍微简单一些 &#xff08;因为当…

实时语音交互,打造更加智能便捷的应用

随着人工智能和自然语言处理技术的进步&#xff0c;用户对智能化和便捷化应用的需求不断增加。语音交互技术以其直观的语音指令&#xff0c;革新了传统的手动输入方式&#xff0c;简化了用户操作&#xff0c;让应用变得更加易用和高效。 通过语音交互&#xff0c;用户可以在不…

Android入门

下载Android studio&#xff0c;创建第一个项目 模板可以选择empty views Activity 在这个界面可以修改&#xff0c;使用语言&#xff0c;项目名字&#xff0c;存储路径以及适用版本 完成后&#xff0c;得到一个最初始的Android 项目&#xff0c;红色标记的两个文件&#xf…

七星创客:重塑商业模式认知

近期&#xff0c;一个普遍存在的疑问困扰着许多人&#xff1a;“商业模式是否仅仅等同于拉人头或传销活动&#xff1f;”这样的联想或许源于对商业模式概念的片面理解&#xff0c;使得一些人错误地将所有商业模式都笼罩在负面阴影之下。 商业模式&#xff0c;这一商业领域的核心…

(IDEA)spring项目导入本地jar包方法和项目打包时找不到引入本地jar包的问题解决方案

系列文章目录 文章目录 系列文章目录一、&#xff08;IDEA&#xff09;spring项目导入本地jar包方法和项目打包时找不到引入本地jar包的问题解决方案1.资料 一、&#xff08;IDEA&#xff09;spring项目导入本地jar包方法和项目打包时找不到引入本地jar包的问题解决方案 1.资料…

Windows11系统下SkyWalking环境搭建教程

目录 前言SkyWalking简介SkyWalking下载Agent监控实现启动配置SkyWalking启动Java应用程序启动Elasticsearch安装总结 前言 本文为博主在项目环境搭建时记录的SkyWalking安装流程&#xff0c;希望对大家能够有所帮助&#xff0c;不足之处欢迎批评指正&#x1f91d;&#x1f91…

828华为云征文|华为云Flexus云服务器X实例部署 即时通讯IM聊天交友软件——高性能服务器实现120W并发连接

营运版的即时通讯IM聊天交友系统&#xff1a;特点可发红包&#xff0c;可添加多条链接到用户网站和应用&#xff0c;安卓苹果APPPC端H5四合一 后端开发语言&#xff1a;PHP&#xff0c; 前端开发语言&#xff1a;uniapp混合开发。 集安卓苹果APPPC端H5四合一APP源码&#xff0…

微信小程序——婚礼邀请函

目的 1.掌握微信小程序的开发技术&#xff0c;包括页面布局、交互设计、数据存储等。 2.学会运用微信小程序的各种组件和 API&#xff0c;实现个性化的婚礼邀请函功能。 3.通过制作婚礼邀请函小程序&#xff0c;提升创意设计和用户体验优化的能力。 4.了解如何在小程序中整…

JAVA并发编程系列(11)线程池底层原理架构剖析

面试官&#xff1a;说说JAVA线程池的几个核心参数&#xff1f; 之前我们用了10篇文章详细剖析了synchronized、volatile、CAS、AQS、ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier、并发锁、Condition等各个核心基础原理&#xff0c;今天开始我们说说并发领域的各种…

信息安全数学基础(24)模为奇数的平方剩余与平方非剩余

前言 在信息安全数学基础中&#xff0c;模为奇数的平方剩余与平方非剩余是数论中的一个重要概念&#xff0c;特别是在密码学和安全协议中扮演着关键角色。当模数为奇数时&#xff0c;我们通常关注的是模为奇素数的平方剩余与平方非剩余&#xff0c;因为奇合数的情况更为复杂且…

自己做个国庆75周年头像生成器

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 下载相关代码&#xff1a;【免费】《自己做个国庆75周年头像生成器》代码资源-CSDN文库 又是一年国庆节&#xff0c;今年使用国旗做…

智慧城市交通管理中的云端多车调度与控制

城市交通管理中的云端多车调度与控制 智慧城市是 21世纪的城市基本发展方向&#xff0c;为了实现智慧城市建设的目标&#xff0c;人们需要用现代化的手段去管理和控制城市中的各种资源和设施。智能交通控制与管理是智慧城市中不可缺少的一部分&#xff0c;因为现代城市交通系统…

【2024工业3D异常检测文献】CMDIAD: 基于跨模态蒸馏驱动的多模态工业异常检测

Incomplete Multimodal Industrial Anomaly Detection via Cross-Modal Distillation 1、Background 近年来&#xff0c;基于3D点云和RGB图像的多模态工业异常检测(IAD)研究强调了利用模态间的冗余性和互补性对于精确分类和分割的重要性。 在项目中&#xff0c;提出了CMDIAD方…

亲身体验Llama 3.1:开源模型的部署与应用之旅

文章目录 1 Llama 3.1系列的诞生2 大型模型的未来发展3 使用教程4 Llama 3.1在客户服务中的运用 1 Llama 3.1系列的诞生 在人工智能的浪潮中&#xff0c;大型语言模型&#xff08;LLM&#xff09;正以其独特的魅力和潜力&#xff0c;成为深度学习领域的一颗耀眼明星。 这些模…

大模型增量训练--基于transformer制作一个大模型聊天机器人

针对夸夸闲聊数据集&#xff0c;利用UniLM模型进行模型训练及测试&#xff0c;更深入地了解预训练语言模型的使用方法&#xff0c;完成一个生成式闲聊机器人任务。 项目主要结构如下&#xff1a; data 存放数据的文件夹 dirty_word.txt 敏感词数据douban_kuakua_qa.txt 原始语…