力扣练习题(2024/4/14)

1接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

单调栈思路:

这个解法和之前给出的Python实现思路是相同的,只是采用了C++语言来实现,并且在处理相同高

  1. 找到每个柱子的左右边界:对于每个柱子,我们需要找到它的左右边界,这样才能确定它能够接多少雨水。左边界是指在当前柱子左侧且高度大于等于当前柱子高度的最近柱子,右边界是指在当前柱子右侧且高度大于等于当前柱子高度的最近柱子。

  2. 单调栈处理逻辑 主要就是三种情况
  3. 情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]
  4. 情况二:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]
  5. 情况三:当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]
  6. 初始化栈:首先,我们创建了一个栈 st,用来存储数组中柱子的索引。我们从数组的第一个柱子开始遍历,将第一个柱子的索引压入栈中。

  7. 遍历数组:从数组的第二个柱子开始,我们开始遍历整个数组。

  8. 处理高度小于栈顶的情况:如果当前柱子的高度小于等于栈顶柱子的高度,我们将当前柱子的索引压入栈中,因为当前柱子无法形成凹槽,无法接水。

  9. 处理高度等于栈顶的情况:如果当前柱子的高度等于栈顶柱子的高度,我们将栈顶柱子的索引弹出,然后将当前柱子的索引压入栈中。这一步的作用是更新相同高度柱子的位置,因为无论哪个位置的柱子,对最后的结果没有影响。

  10. 处理高度大于栈顶的情况:如果当前柱子的高度大于栈顶柱子的高度,说明可能会形成凹槽,可以接雨水。我们不断弹出栈顶元素,直到栈为空或者当前柱子的高度小于等于栈顶柱子的高度。在弹出栈顶元素的过程中,我们计算相邻柱子之间能够接的雨水量,并累加到结果 sum 中。

  11. 计算雨水量:在每次弹出栈顶元素时,我们计算当前柱子和栈顶元素之间的距离 w,以及能够接到的雨水高度 h,然后将 h * w 累加到结果 sum 中。

  12. 更新栈:处理完当前柱子后,将当前柱子的索引压入栈中,继续处理下一个柱子。

  13. 返回结果:最后,当遍历完整个数组后,返回累加的结果 sum,即为能够接到的总雨水量。

代码:

class Solution {
public:int trap(vector<int>& height) {// 如果柱子数量小于等于2,则无法形成凹槽,无法接雨水,直接返回0if (height.size() <= 2) return 0;int sum = 0; // 存储能接到的总雨水量stack<int> st; // 单调递减栈,用来存储柱子的索引st.push(0); // 将第一个柱子的索引压入栈中// 从数组的第二个柱子开始遍历for (int i = 1; i < height.size(); i++) {// 处理当前柱子高度小于等于栈顶柱子的情况if (height[i] <= height[st.top()]) {st.push(i); // 将当前柱子的索引压入栈中}// 处理当前柱子高度等于栈顶柱子的情况else if (height[i] == height[st.top()]) {st.pop(); // 可以不加,效果是一样的,但处理相同的情况的思路却变了。st.push(i); // 将当前柱子的索引压入栈中,更新相同高度柱子的位置}// 处理当前柱子高度大于栈顶柱子的情况else {// 不断弹出栈顶元素,直到栈为空或者当前柱子的高度小于等于栈顶柱子的高度while (!st.empty() && height[i] > height[st.top()]) {int mid = st.top(); // 当前柱子的左边界st.pop();if (!st.empty()) {// 计算能接到的雨水量int h = min(height[st.top()], height[i]) - height[mid]; // 高度差int w = i - st.top() - 1; // 宽度sum += h * w; // 累加到结果中}}st.push(i); // 将当前柱子的索引压入栈中}}return sum; // 返回总雨水量}
};

2柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例 2:

输入: heights = [2,4]
输出: 4

提示:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

单调栈思路:本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!

  1. 单调递减栈:创建一个单调递减栈,用于存储柱子的索引。栈内元素按照柱子的高度递减排列。

  2. 遍历柱子:从左到右遍历柱子,对于每个柱子,执行以下操作:

    • 如果当前栈为空或者当前柱子的高度大于栈顶柱子的高度,则将当前柱子的索引压入栈中。这样可以保证栈内元素的高度是单调递减的,且每个柱子能找到其向左最近的比它低的柱子。

    • 如果当前柱子的高度等于栈顶柱子的高度,则说明当前柱子和栈顶柱子的高度相同,这种情况下,栈顶元素的位置无关紧要,所以将栈顶柱子的索引弹出,然后将当前柱子的索引压入栈中,以更新相同高度柱子的位置。

    • 如果当前柱子的高度小于栈顶柱子的高度,则说明当前柱子无法向右扩展形成更大的矩形面积。因此,需要不断弹出栈顶元素,直到栈为空或者当前柱子的高度大于栈顶柱子的高度为止。在弹出栈顶元素的过程中,可以计算以弹出柱子为高度的矩形的面积,并更新最大矩形面积。

  3. 计算矩形面积:在每次弹出栈顶元素时,计算以弹出柱子为高度的矩形的面积。矩形的宽度可以通过当前柱子的索引和栈顶元素的索引来计算。

  4. 更新最大矩形面积:每次计算出矩形的面积后,将其与当前的最大矩形面积进行比较,取较大值作为最大矩形面积。

  5. 返回结果:遍历完所有柱子后,得到的最大矩形面积即为所求结果。

在处理柱状图中最大矩形的问题时,在数组的两端加入高度为0的柱子是一种常用的技巧,这样做的目的是为了处理边界情况。

  1. 处理左边界情况:在数组的开头插入一个高度为0的柱子,这样做是为了确保整个数组都能被处理到。如果不在开头插入一个高度为0的柱子,那么对于数组的第一个柱子,它的左边界将无法确定。如果数组本身是降序的,例如 [8,6,4,2],在 8 入栈后,6 开始与8 进行比较,此时我们得到 mid(8),rigt(6),但是得不到 left。因为 将 8 弹出之后,栈里没有元素了,那么为了避免空栈取值,直接跳过了计算结果的逻辑。之后又将6 加入栈(此时8已经弹出了),然后 就是 4 与 栈口元素 8 进行比较,周而复始,那么计算的最后结果resutl就是0

  2. 处理右边界情况:在数组的末尾插入一个高度为0的柱子,这样做是为了确保所有柱子都能被弹出栈并计算对应的矩形面积。如果不在末尾插入一个高度为0的柱子,那么在遍历完所有柱子后,可能还会剩余一些柱子留在栈中,无法找到右边界。如果数组本身就是升序的,例如[2,4,6,8],那么入栈之后 都是单调递减,一直都没有走 当前遍历的元素heights[i]小于栈顶元素heights[st.top()]的情况 计算结果的哪一步,所以最后输出的就是0了

代码:

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int result = 0; // 存储最大矩形面积的变量stack<int> st; // 单调递增栈,用于存储柱子的索引heights.insert(heights.begin(), 0); // 在柱子数组的开头插入一个高度为0的柱子,方便处理边界情况heights.push_back(0); // 在柱子数组的末尾插入一个高度为0的柱子,方便处理边界情况st.push(0); // 将第一个柱子的索引压入栈中// 从第二个柱子开始遍历for(int i = 1; i < heights.size(); i++) {// 处理当前柱子高度大于栈顶柱子高度的情况if(heights[i] > heights[st.top()]) {st.push(i); // 将当前柱子的索引压入栈中} // 处理当前柱子高度等于栈顶柱子高度的情况else if(heights[i] == heights[st.top()]) {st.pop(); // 可以不加,效果是一样的,但处理相同的情况的思路却变了。st.push(i); // 将当前柱子的索引压入栈中,更新相同高度柱子的位置} // 处理当前柱子高度小于栈顶柱子高度的情况else {// 不断弹出栈顶元素,直到栈为空或者当前柱子的高度大于栈顶柱子的高度while(!st.empty() && heights[i] < heights[st.top()]) {int mid = st.top(); // 当前柱子的索引,即矩形的高度st.pop(); // 弹出栈顶元素if(!st.empty()) {int left = st.top(); // 左边界的索引int right = i; // 右边界的索引int w = right - left - 1; // 矩形的宽度int h = heights[mid]; // 矩形的高度result = max(result, w * h); // 更新最大矩形面积}}st.push(i); // 将当前柱子的索引压入栈中}}return result; // 返回最大矩形面积}
};

3销售分析III

表: Product

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| product_id   | int     |
| product_name | varchar |
| unit_price   | int     |
+--------------+---------+
product_id 是该表的主键(具有唯一值的列)。
该表的每一行显示每个产品的名称和价格。

表:Sales

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| seller_id   | int     |
| product_id  | int     |
| buyer_id    | int     |
| sale_date   | date    |
| quantity    | int     |
| price       | int     |
+------ ------+---------+
这个表可能有重复的行。
product_id 是 Product 表的外键(reference 列)。
该表的每一行包含关于一个销售的一些信息。

编写解决方案,报告2019年春季才售出的产品。即2019-01-012019-03-31(含)之间出售的商品。

以 任意顺序 返回结果表。

结果格式如下所示。

示例 1:

输入:
Product table:
+------------+--------------+------------+
| product_id | product_name | unit_price |
+------------+--------------+------------+
| 1          | S8           | 1000       |
| 2          | G4           | 800        |
| 3          | iPhone       | 1400       |
+------------+--------------+------------+
Sales table:
+-----------+------------+----------+------------+----------+-------+
| seller_id | product_id | buyer_id | sale_date  | quantity | price |
+-----------+------------+----------+------------+----------+-------+
| 1         | 1          | 1        | 2019-01-21 | 2        | 2000  |
| 1         | 2          | 2        | 2019-02-17 | 1        | 800   |
| 2         | 2          | 3        | 2019-06-02 | 1        | 800   |
| 3         | 3          | 4        | 2019-05-13 | 2        | 2800  |
+-----------+------------+----------+------------+----------+-------+
输出:
+-------------+--------------+
| product_id  | product_name |
+-------------+--------------+
| 1           | S8           |
+-------------+--------------+
解释:
id 为 1 的产品仅在 2019 年春季销售。
id 为 2 的产品在 2019 年春季销售,但也在 2019 年春季之后销售。
id 为 3 的产品在 2019 年春季之后销售。
我们只返回 id 为 1 的产品,因为它是 2019 年春季才销售的产品。

思路:

  1. 选择需要的列:首先,我们从产品表(Product)中选择了产品ID(product_id)和产品名称(product_name)这两个列。

  2. 左连接销售表:通过使用 left join,我们将产品表和销售表(Sales)连接起来。这样做是为了获取销售信息,并且即使某些产品没有销售记录,也能够保留它们的信息。

  3. 根据产品ID分组:接着,我们使用 GROUP BY 子句,按照销售表中的产品ID进行分组。这样做是为了确保每个产品只出现一次,以便后续进行聚合操作。

  4. 筛选满足条件的数据:在 GROUP BY 后,我们使用 HAVING 子句来筛选满足特定条件的数据。这个条件是销售日期在 ‘2019-01-01’ 到 ‘2019-03-31’ 之间的产品。我们使用 MAX 函数和 MIN 函数来找到每个产品的最大销售日期和最小销售日期,并将其与指定的日期范围进行比较。

代码:

-- 选择产品表中的产品ID和产品名称
select p.product_id, p.product_name
-- 从产品表(Product)中选择数据,并左连接销售表(Sales)
from Product as p
left join Sales as s
on p.product_id = s.product_id
-- 根据销售表中的产品ID进行分组
group by s.product_id
-- 使用 HAVING 子句筛选满足条件的数据,即销售日期在指定范围内的产品
having max(s.sale_date) <= '2019-03-31' and min(s.sale_date) >= '2019-01-01';

4查询近30天活跃用户数

表:Activity

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| user_id       | int     |
| session_id    | int     |
| activity_date | date    |
| activity_type | enum    |
+---------------+---------+
该表没有包含重复数据。
activity_type 列是 ENUM(category) 类型, 从 ('open_session', 'end_session', 'scroll_down', 'send_message') 取值。
该表记录社交媒体网站的用户活动。
注意,每个会话只属于一个用户。

编写解决方案,统计截至 2019-07-27(包含2019-07-27),近 30 天的每日活跃用户数(当天只要有一条活动记录,即为活跃用户)。

以 任意顺序 返回结果表。

结果示例如下。

示例 1:

输入:
Activity table:
+---------+------------+---------------+---------------+
| user_id | session_id | activity_date | activity_type |
+---------+------------+---------------+---------------+
| 1       | 1          | 2019-07-20    | open_session  |
| 1       | 1          | 2019-07-20    | scroll_down   |
| 1       | 1          | 2019-07-20    | end_session   |
| 2       | 4          | 2019-07-20    | open_session  |
| 2       | 4          | 2019-07-21    | send_message  |
| 2       | 4          | 2019-07-21    | end_session   |
| 3       | 2          | 2019-07-21    | open_session  |
| 3       | 2          | 2019-07-21    | send_message  |
| 3       | 2          | 2019-07-21    | end_session   |
| 4       | 3          | 2019-06-25    | open_session  |
| 4       | 3          | 2019-06-25    | end_session   |
+---------+------------+---------------+---------------+
输出:
+------------+--------------+ 
| day        | active_users |
+------------+--------------+ 
| 2019-07-20 | 2            |
| 2019-07-21 | 2            |
+------------+--------------+ 
解释:注意非活跃用户的记录不需要展示。

代码:

-- 选择活动日期(activity_date)作为日期,以及计算每天活跃用户的数量
select activity_date as day, count(distinct user_id) as active_users
-- 从活动表(Activity)中选择数据
from Activity
-- 筛选出日期在 '2019-06-28' 到 '2019-07-27' 之间的记录
where activity_date <= '2019-07-27' and activity_date > '2019-06-27'
-- 根据活动日期进行分组
group by activity_date;

5 文章浏览 I

Views 表:

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| article_id    | int     |
| author_id     | int     |
| viewer_id     | int     |
| view_date     | date    |
+---------------+---------+
此表可能会存在重复行。(换句话说,在 SQL 中这个表没有主键)
此表的每一行都表示某人在某天浏览了某位作者的某篇文章。
请注意,同一人的 author_id 和 viewer_id 是相同的。

请查询出所有浏览过自己文章的作者

结果按照 id 升序排列。

查询结果的格式如下所示:

示例 1:

输入:
Views 表:
+------------+-----------+-----------+------------+
| article_id | author_id | viewer_id | view_date  |
+------------+-----------+-----------+------------+
| 1          | 3         | 5         | 2019-08-01 |
| 1          | 3         | 6         | 2019-08-02 |
| 2          | 7         | 7         | 2019-08-01 |
| 2          | 7         | 6         | 2019-08-02 |
| 4          | 7         | 1         | 2019-07-22 |
| 3          | 4         | 4         | 2019-07-21 |
| 3          | 4         | 4         | 2019-07-21 |
+------------+-----------+-----------+------------+输出:
+------+
| id   |
+------+
| 4    |
| 7    |
+------+

代码:

select distinct author_id as id
from Views
where author_id = viewer_id
order by 1;

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于LSTM的新闻中文文本分类——基于textCNN与textRNN

构建词语字典 def build_vocab(file_path, tokenizer, max_size, min_freq):# 定义词汇表字典&#xff1a;使用 vocab_dic {} 初始化一个空字典&#xff0c;用于存储每个词及其出现频率vocab_dic {}with open(file_path, r, encodingUTF-8) as f:for line in tqdm(f):lin l…

新零售门店、商品、会员管理指标体系总览

新零售&#xff0c;旨在打破传统零售业的边界&#xff0c;引入先进科技和数字化手段&#xff0c;通过整合线上线下渠道&#xff0c;全面提升用户体验&#xff0c;并实现更智能、高效、个性化的零售运营模式。这一模式不仅仅关注销售产品&#xff0c;更注重构建全方位的购物生态…

都2024年了,线上部署你不会只会log 调试吧,Arthas了解下!

文章目录 一、什么是Arthas&#xff1f;⛅背景⚡Arthas能为我们做什么 二、部署Arthas三、Arthas 基础命令四、Arthas 项目命令实战⌚thread 线程阻塞⏰watch命令演示⚡cpu飙升演示⛽方法演示 &#x1f6a8;小结 一、什么是Arthas&#xff1f; Arthas 是一款线上监控诊断产品&a…

智能网络新纪元:机器学习赋能未来计算机网络高速发展

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导…

基于Java+SpringBoot+Vue前后端分离精简博客系统设计和实现

基于JavaSpringBootVue前后端分离精简博客系统设计和实现 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系…

【Spring Security系列】一文带你了解权限框架与Spring Security核心概念

权限框架 权限框架是软件开发中用于管理用户权限和访问控制的工具。在企业或者我们毕设复杂的系统中&#xff0c;不同的用户或角色需要拥有不同的访问和操作权限&#xff0c;以确保系统的安全性和数据完整性。今天我们就讨论一下Java中的安全框架&#xff01; 流行的安全框架…

利用vite创建vue项目

创建vue项目步骤 打开HBuilder X工具&#xff0c;创建空白项目 进入终端(鼠标点击文件进行选择&#xff0c;然后终端) 利用vite脚手架创建项目 &#xff08;前提要将HBuilder X工具属性设为管理员运行状态&#xff08;属性》兼容》管理员身份运行此程序&#xff09; npm …

【QT入门】Qt自定义控件与样式设计之鼠标相对、绝对位置、窗口位置、控件位置

往期回顾 【QT入门】 Qt自定义控件与样式设计之QSlider用法及qss-CSDN博客 【QT入门】Qt自定义控件与样式设计之qss的加载方式-CSDN博客 【QT入门】Qt自定义控件与样式设计之控件提升与自定义控件-CSDN博客 【QT入门】Qt自定义控件与样式设计之鼠标相对、绝对位置、窗口位置、控…

BEVFormer代码阅读

1. 代码地址 https://github.com/fundamentalvision/BEVFormer 2. 代码结构 个人理解&#xff0c;代码库中的代码与两篇论文都略有不同&#xff0c;总结起来&#xff0c;其结构如下。 3. BEVFormer 的 Pipeline 根据自己调试算法模型以及对论文的理解&#xff0c;我这里将 …

用html写一个雨的特效

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>雨特效</title><link rel"stylesheet" href"./style.css"> </head> <body> <div id"wrap-textu…

【御控物联】物联网平台设备接入-JSON数据格式转化(场景案例四)

文章目录 一、背景二、解决方案三、在线转换工具四、技术资料 一、背景 物联网平台是一种实现设备接入、设备监控、设备管理、数据存储、消息多源转发和数据分析等能力的一体化平台。南向支持连接海量异构&#xff08;协议多样&#xff09;设备&#xff0c;实现设备数据云端存…

02 SQL基础 -- 初识SQL

一、初识 SQL 1.1 概念介绍 数据库中存储的表结构类似于 excel 中的行和列,在数据库中,行称为记录,它相当于一条结论,列称为字段,它代表了表中存储的数据项目 行和列交汇的地方称为单元格,一个单元格只能输入一条记录 SQL是为操作数据库而开发的语言。国际标准化组织(…