目录
题目
思路
Code
小华之前玩过一个游戏,在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤i≤ n)个矩形的高度为 h[i], 这 n 个短形构成了一个直方图,在直方图中我留能够勾勒出来的矩形的最大面积。这个游戏小华已经玩得很腻了,于是小华就想增加一下难度,现在有1次交换任意2个矩形的操作,请问在交换后,能够勾勒出的最大的短形面积能达到多少呢?
输入描述
第-行包含一个整数 n(2 < n < 10^5),表示矩形个数。
第二行包含n个整数,依次为 h[1],h[2],…, h[n](1 < h[i] < 10^4),表示矩形的高度
输出描述
输出一个整数,表示在交换后能够勾勒出的最大的矩形面积,
示例1:
输入:
6
3 1 6 5 2 3输出:
12示例2:
输入:
7
5 5 3 5 5 2 4输出:
20
1. 问题分析
1.1 题目理解
输出要求的具体说明:
- 计算经过一次交换操作后,直方图中最大矩形的面积
- 矩形必须是连续的,高度由覆盖范围内的最小柱子决定
约束条件的整理:
- 只能进行一次交换操作(交换任意两个矩形)
- 矩形宽度必须连续,高度受限于范围内最矮的柱子
- 需要考虑所有可能的交换情况
1.2 问题建模
数据结构转化:
- 将问题转化为:对于每个可能的矩形高度h,计算能形成的最大连续区域
- 关键洞察:可以交换使得所有高度≥h的矩形聚集在一起
算法类型确定:
- 贪心算法:对每个高度值,计算其可能的最大连续区域面积
- 不需要枚举所有交换情况,而是基于高度值进行优化
数学模型:
- 对于高度值h,设count为高度≥h的矩形数量
- 通过交换可以使这count个矩形连续排列
- 对应的最大矩形面积为:h × count
2. 解题思路
2.1 算法选择
最优算法:基于高度值的贪心算法
- 核心思想:通过交换可以将高度≥某个值的所有矩形聚集在一起
- 对每个可能的高度值计算最大面积,取全局最大值
复杂度分析:
- 时间复杂度:O(n log n),主要是排序的复杂度
- 空间复杂度:O(n),存储高度数组和计数
2.2 核心数据结构
主要数据结构选择:
- 使用排序后的高度数组进行遍历
- 使用计数器统计每个高度值对应的矩形数量
实现方式:
- 对高度数组排序并去重
- 对每个高度值,计算≥该高度的矩形总数
- 计算对应的矩形面积
2.3 关键算法步骤
- 预处理:对所有高度值进行排序和去重
- 贪心计算:
- 对每个不同的高度值h
- 计算高度≥h的矩形数量count
- 计算可能的最大面积:h × count
- 全局最优:返回所有可能面积中的最大值
def solve():
"""
计算经过一次交换后直方图的最大矩形面积
Returns:
int: 最大矩形面积
"""
# 读取输入
n = int(input())
heights = list(map(int, input().split()))
# 核心思想:对于任意高度h,我们可以通过交换将所有高度>=h的矩形聚集在一起
# 这样可以形成一个连续区域,其最大矩形面积为 h * count(高度>=h的矩形数量)
# 获取所有不同的高度值并排序
unique_heights = sorted(set(heights), reverse=True)
max_area = 0
# 对每个可能的高度值进行计算
for h in unique_heights:
# 计算高度大于等于h的矩形数量
count = sum(1 for height in heights if height >= h)
# 通过交换,我们可以让这count个矩形连续排列
# 形成一个高度为h,宽度为count的矩形
area = h * count
# 更新最大面积
max_area = max(max_area, area)
return max_area
# 输出结果
print(solve())
import java.util.*;
public class HistogramMaxArea {
/**
* 计算经过一次交换后直方图的最大矩形面积
*
* @return 最大矩形面积
*/
public static int solve() {
Scanner scanner = new Scanner(System.in);
// 读取输入
int n = scanner.nextInt();
int[] heights = new int[n];
for (int i = 0; i < n; i++) {
heights[i] = scanner.nextInt();
}
// 核心思想:对于任意高度h,我们可以通过交换将所有高度>=h的矩形聚集在一起
// 这样可以形成一个连续区域,其最大矩形面积为 h * count(高度>=h的矩形数量)
// 获取所有不同的高度值并排序(降序)
Set heightSet = new HashSet<>();
for (int height : heights) {
heightSet.add(height);
}
List uniqueHeights = new ArrayList<>(heightSet);
Collections.sort(uniqueHeights, Collections.reverseOrder());
int maxArea = 0;
// 对每个可能的高度值进行计算
for (int h : uniqueHeights) {
// 计算高度大于等于h的矩形数量
int count = 0;
for (int height : heights) {
if (height >= h) {
count++;
}
}
// 通过交换,我们可以让这count个矩形连续排列
// 形成一个高度为h,宽度为count的矩形
int area = h * count;
// 更新最大面积
maxArea = Math.max(maxArea, area);
}
scanner.close();
return maxArea;
}
/**
* 主函数
*/
public static void main(String[] args) {
System.out.println(solve());
}
}
#include
#include
#include
#include
using namespace std;
/**
* 计算经过一次交换后直方图的最大矩形面积
*
* @return 最大矩形面积
*/
int solve() {
// 读取输入
int n;
cin >> n;
vector heights(n);
for (int i = 0; i < n; i++) {
cin >> heights[i];
}
// 核心思想:对于任意高度h,我们可以通过交换将所有高度>=h的矩形聚集在一起
// 这样可以形成一个连续区域,其最大矩形面积为 h * count(高度>=h的矩形数量)
// 获取所有不同的高度值并排序(降序)
set heightSet(heights.begin(), heights.end());
vector uniqueHeights(heightSet.rbegin(), heightSet.rend());
int maxArea = 0;
// 对每个可能的高度值进行计算
for (int h : uniqueHeights) {
// 计算高度大于等于h的矩形数量
int count = 0;
for (int height : heights) {
if (height >= h) {
count++;
}
}
// 通过交换,我们可以让这count个矩形连续排列
// 形成一个高度为h,宽度为count的矩形
int area = h * count;
// 更新最大面积
maxArea = max(maxArea, area);
}
return maxArea;
}
/**
* 主函数
*/
int main() {
cout << solve() << endl;
return 0;
}
/**
* 计算经过一次交换后直方图的最大矩形面积
*
* @returns {number} 最大矩形面积
*/
function solve() {
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let lineCount = 0;
let n, heights;
rl.on('line', (line) => {
if (lineCount === 0) {
// 读取矩形个数
n = parseInt(line);
lineCount++;
} else {
// 读取高度数组
heights = line.split(' ').map(Number);
// 核心思想:对于任意高度h,我们可以通过交换将所有高度>=h的矩形聚集在一起
// 这样可以形成一个连续区域,其最大矩形面积为 h * count(高度>=h的矩形数量)
// 获取所有不同的高度值并排序(降序)
const heightSet = new Set(heights);
const uniqueHeights = Array.from(heightSet).sort((a, b) => b - a);
let maxArea = 0;
// 对每个可能的高度值进行计算
for (const h of uniqueHeights) {
// 计算高度大于等于h的矩形数量
let count = 0;
for (const height of heights) {
if (height >= h) {
count++;
}
}
// 通过交换,我们可以让这count个矩形连续排列
// 形成一个高度为h,宽度为count的矩形
const area = h * count;
// 更新最大面积
maxArea = Math.max(maxArea, area);
}
console.log(maxArea);
rl.close();
}
});
}
// 运行求解函数
solve();
#include
#include
/**
* 比较函数,用于降序排序
*/
int compare(const void *a, const void *b) {
return (*(int*)b - *(int*)a);
}
/**
* 计算经过一次交换后直方图的最大矩形面积
*
* @return 最大矩形面积
*/
int solve() {
int n;
// 读取输入
scanf("%d", &n);
int heights[n];
for (int i = 0; i < n; i++) {
scanf("%d", &heights[i]);
}
// 核心思想:对于任意高度h,我们可以通过交换将所有高度>=h的矩形聚集在一起
// 这样可以形成一个连续区域,其最大矩形面积为 h * count(高度>=h的矩形数量)
// 获取所有不同的高度值
int uniqueHeights[n];
int uniqueCount = 0;
// 去重:将所有高度值复制并排序去重
for (int i = 0; i < n; i++) {
int found = 0;
for (int j = 0; j < uniqueCount; j++) {
if (uniqueHeights[j] == heights[i]) {
found = 1;
break;
}
}
if (!found) {
uniqueHeights[uniqueCount++] = heights[i];
}
}
// 对不同的高度值进行降序排序
qsort(uniqueHeights, uniqueCount, sizeof(int), compare);
int maxArea = 0;
// 对每个可能的高度值进行计算
for (int i = 0; i < uniqueCount; i++) {
int h = uniqueHeights[i];
// 计算高度大于等于h的矩形数量
int count = 0;
for (int j = 0; j < n; j++) {
if (heights[j] >= h) {
count++;
}
}
// 通过交换,我们可以让这count个矩形连续排列
// 形成一个高度为h,宽度为count的矩形
int area = h * count;
// 更新最大面积
if (area > maxArea) {
maxArea = area;
}
}
return maxArea;
}
/**
* 主函数
*/
int main() {
printf("%d\n", solve());
return 0;
}
【华为od机试真题Python+JS+Java合集】【超值优惠】:Py/JS/Java合集
【华为od机试真题Python】:Python真题题库
【华为od机试真题JavaScript】:JavaScript真题题库
【华为od机试真题Java】:Java真题题库
【华为od机试真题C++】:C++真题题库
【华为od机试真题C语言】:C语言真题题库
【华为od面试手撕代码题库】:面试手撕代码题库
【华为校招&实习机试面试交流群:1048120678】