452. Minimum Number of Arrows to Burst Balloons

探讨如何通过最少次数的射箭来爆破所有水平分布的气球。文章介绍了一种排序方法,并提供了两种解决方案:一是使用最小堆处理结束坐标;二是简化为单一变量跟踪最小结束坐标。

原题网址:https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/

There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it's horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 104 balloons.

An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons.

Example:

Input:
[[10,16], [2,8], [1,6], [7,12]]

Output:
2

Explanation:
One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).

思路:与会议室、排课表问题类似,先对开始坐标进行排序。当遇到一个结束坐标时,该气球必须被戳爆,顺带戳爆其他的气球。

方法一:先对开始坐标排序,再用最小堆处理结束坐标。

public class Solution {
    public int findMinArrowShots(int[][] points) {
        Arrays.sort(points, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                return a[0] - b[0];
            }
        });
        
        PriorityQueue<int[]> minHeap = new PriorityQueue<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                return a[1] - b[1];
            }
        });
        int shots = 0;
        for(int i = 0; i < points.length; i++) {
            if (!minHeap.isEmpty() && points[i][0] > minHeap.peek()[1]) {
                shots++;
                minHeap.clear();
            }
            minHeap.offer(points[i]);
        }
        if (!minHeap.isEmpty()) {
            shots++;
        }
        return shots;
    }
}

方法二:最小堆可以简化为一个变量。

public class Solution {
    public int findMinArrowShots(int[][] points) {
        Arrays.sort(points, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                return a[0] - b[0];
            }
        });

        int shots = 0;
        boolean hasMin = false;
        int minValue = Integer.MIN_VALUE;
        for(int i = 0; i < points.length; i++) {
            if (!hasMin) {
                minValue = points[i][1];
                hasMin = true;
            } else if (points[i][0] > minValue) {
                shots++;
                minValue = points[i][1];
            } else {
                minValue = Math.min(minValue, points[i][1]);
            }
        }
        if (hasMin) {
            shots++;
        }
        return shots;
    }
}


以下是一个使用 HTML、CSS 和 JavaScript 实现的数学应用,用于计算**众数(Mode)**和**中位数(Median)**。该应用包含: - 一个按钮生成随机数据集 - 箭头按钮来增加或减少数据集大小 - 一个按钮对数据集排序 - 按钮分别显示众数和中位数 --- ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Mode and Median Calculator</title> <style> body { font-family: Arial, sans-serif; margin: 40px; background-color: #f4f6f9; color: #333; } h1 { text-align: center; color: #2c3e50; } .container { max-width: 800px; margin: 0 auto; padding: 20px; background-color: #fff; border-radius: 10px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); } .controls { display: flex; justify-content: center; align-items: center; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; } button { padding: 10px 15px; font-size: 16px; cursor: pointer; background-color: #3498db; color: white; border: none; border-radius: 5px; transition: background-color 0.3s; } button:hover { background-color: #2980b9; } .data-display { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; min-height: 50px; word-break: break-all; } .size-control { display: flex; align-items: center; gap: 10px; } .result { margin-top: 15px; font-weight: bold; color: #27ae60; } </style> </head> <body> <div class="container"> <h1>Mode and Median Calculator</h1> <div class="controls"> <button id="generate">Generate Random Data</button> <div class="size-control"> <button id="decrease">←</button> <span id="size">Size: 10</span> <button id="increase">→</button> </div> <button id="sort">Sort Data</button> <button id="showMode">Show Mode</button> <button id="showMedian">Show Median</button> </div> <h3>Data Set:</h3> <div class="data-display" id="dataDisplay"></div> <div class="result" id="result"></div> </div> <script> // Variables to store dataset and size let dataSize = 10; let data = []; // DOM Elements const dataDisplay = document.getElementById("dataDisplay"); const resultDiv = document.getElementById("result"); const sizeSpan = document.getElementById("size"); // Update data display function updateDisplay() { dataDisplay.textContent = data.join(", "); resultDiv.textContent = ""; } // Generate random dataset function generateRandomData() { data = Array.from({ length: dataSize }, () => Math.floor(Math.random() * 100)); updateDisplay(); } // Sort the dataset function sortData() { if (data.length === 0) return; data.sort((a, b) => a - b); updateDisplay(); } // Calculate mode function calculateMode() { if (data.length === 0) return "No data"; const frequency = {}; let maxCount = 0; let modes = []; // Count frequencies data.forEach(num => { frequency[num] = (frequency[num] || 0) + 1; if (frequency[num] > maxCount) maxCount = frequency[num]; }); // Find all numbers with maximum frequency for (let num in frequency) { if (frequency[num] === maxCount) { modes.push(Number(num)); } } return modes.length === Object.keys(frequency).length ? "No mode" : modes.join(", "); } // Calculate median function calculateMedian() { if (data.length === 0) return "No data"; const sorted = [...data].sort((a, b) => a - b); const mid = Math.floor(sorted.length / 2); if (sorted.length % 2 === 0) { return (sorted[mid - 1] + sorted[mid]) / 2; } else { return sorted[mid]; } } // Event Listeners document.getElementById("generate").addEventListener("click", generateRandomData); document.getElementById("increase").addEventListener("click", () => { dataSize += 1; sizeSpan.textContent = `Size: ${dataSize}`; generateRandomData(); }); document.getElementById("decrease").addEventListener("click", () => { if (dataSize > 1) { dataSize -= 1; sizeSpan.textContent = `Size: ${dataSize}`; generateRandomData(); } }); document.getElementById("sort").addEventListener("click", sortData); document.getElementById("showMode").addEventListener("click", () => { const mode = calculateMode(); resultDiv.textContent = `Mode: ${mode}`; }); document.getElementById("showMedian").addEventListener("click", () => { const median = calculateMedian(); resultDiv.textContent = `Median: ${median}`; }); // Initialize on load generateRandomData(); </script> </body> </html> ``` --- ### 🔍 解释: - **HTML 结构**:创建了按钮区、数据显示区和结果输出。 - **CSS 样式**:使界面美观、响应式,适合桌面和移动端。 - **JavaScript 功能**: - `generateRandomData()`:生成指定长度的随机整数数组(范围 0–99)。 - `sortData()`:升序排序当前数据。 - `calculateMode()`: - 使用对象统计频次; - 找出最高频次的值; - 如果所有值频率相同,则返回“无众数”; - 否则返回众数(可能多个)。 - `calculateMedian()`: - 排序后根据奇偶长度取中间值或中间两数平均值。 - **按钮控制**: - ← 和 → 调整数据集大小并重新生成; - “Show Mode” 和 “Show Median” 分别显示对应统计量。 --- ### ✅ 特性说明: - 支持多众数(如 `[1,1,2,2]` 的众数是 `1, 2`) - 自动在改变大小时刷新数据 - 用户交互清晰,反馈及时 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值