2025.06.11华为暑期实习机试真题【最大的矩形新游戏】Java/Python/C++/JS/C 实现

目录

题目

思路

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 关键算法步骤

  1. 预处理:对所有高度值进行排序和去重
  1. 贪心计算:
  • 对每个不同的高度值h
  • 计算高度≥h的矩形数量count
  • 计算可能的最大面积:h × count
  1. 全局最优:返回所有可能面积中的最大值

Python

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())

 Java

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());
    }
}

 C++

#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;
}

 JavaScript

/**
 * 计算经过一次交换后直方图的最大矩形面积
 * 
 * @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();

 C语言

#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】

你可能感兴趣的:(python,华为,java,c++,华为暑期实习,机试)