当前位置: 首页 > news >正文

LeetCode 3027.人员站位的方案数 II:简单一个排序O(n^2)——ASCII图解

【LetMeFly】3027.人员站位的方案数 II:简单一个排序O(n^2)——ASCII图解

力扣题目链接:https://leetcode.cn/problems/find-the-number-of-ways-to-place-people-ii/

给你一个  n x 2 的二维数组 points ,它表示二维平面上的一些点坐标,其中 points[i] = [xi, yi] 。

我们定义 x 轴的正方向为  (x 轴递增的方向),x 轴的负方向为  (x 轴递减的方向)。类似的,我们定义 y 轴的正方向为  (y 轴递增的方向),y 轴的负方向为  (y 轴递减的方向)。

你需要安排这 n 个人的站位,这 n 个人中包括 Alice 和 Bob 。你需要确保每个点处 恰好 有 一个 人。同时,Alice 想跟 Bob 单独玩耍,所以 Alice 会以 Alice 的坐标为 左上角 ,Bob 的坐标为 右下角 建立一个矩形的围栏(注意,围栏可能  包含任何区域,也就是说围栏可能是一条线段)。如果围栏的 内部 或者 边缘 上有任何其他人,Alice 都会难过。

请你在确保 Alice 不会 难过的前提下,返回 Alice 和 Bob 可以选择的 点对 数目。

注意,Alice 建立的围栏必须确保 Alice 的位置是矩形的左上角,Bob 的位置是矩形的右下角。比方说,以 (1, 1) ,(1, 3) ,(3, 1) 和 (3, 3) 为矩形的四个角,给定下图的两个输入,Alice 都不能建立围栏,原因如下:

  • 图一中,Alice 在 (3, 3) 且 Bob 在 (1, 1) ,Alice 的位置不是左上角且 Bob 的位置不是右下角。
  • 图二中,Alice 在 (1, 3) 且 Bob 在 (1, 1) ,Bob 的位置不是在围栏的右下角。

 

示例 1:

输入:points = [[1,1],[2,2],[3,3]]
输出:0
解释:没有办法可以让 Alice 的围栏以 Alice 的位置为左上角且 Bob 的位置为右下角。所以我们返回 0 。

示例 2:

输入:points = [[6,2],[4,4],[2,6]]
输出:2
解释:总共有 2 种方案安排 Alice 和 Bob 的位置,使得 Alice 不会难过:
- Alice 站在 (4, 4) ,Bob 站在 (6, 2) 。
- Alice 站在 (2, 6) ,Bob 站在 (4, 4) 。
不能安排 Alice 站在 (2, 6) 且 Bob 站在 (6, 2) ,因为站在 (4, 4) 的人处于围栏内。

示例 3:

输入:points = [[3,1],[1,3],[1,1]]
输出:2
解释:总共有 2 种方案安排 Alice 和 Bob 的位置,使得 Alice 不会难过:
- Alice 站在 (1, 1) ,Bob 站在 (3, 1) 。
- Alice 站在 (1, 3) ,Bob 站在 (1, 1) 。
不能安排 Alice 站在 (1, 3) 且 Bob 站在 (3, 1) ,因为站在 (1, 1) 的人处于围栏内。
注意围栏是可以不包含任何面积的,上图中第一和第二个围栏都是合法的。

 

提示:

  • 2 <= n <= 1000
  • points[i].length == 2
  • -109 <= points[i][0], points[i][1] <= 109
  • points[i] 点对两两不同。

解题方法:排序

数据范围是10310^3103,因此可以二重循环:第一层循环枚举左上角的Alice,第二层循环枚举右下角的Bob,如果可以在O(1)时间内判断出Alice和Bob之间有无第三者,问题就解决了。

很容易想到排个序,最左边为最优先,最上边为次优先。

那么,对于一个Alice,在遍历Bob时,我们只需要使用一个变量mxY记录遍历过的合法Bob中最上边的那个。

↑
|           * Bob4
|
|  * Alice
|              *Bob3
|
| - - - * - - - - - - - - mxY
|      Bob1
|
|           * Bob2
|
+---------------------------→↑当前遍历到

例如合法的Bob1会把mxY提高到他的高度,后续所有Bob中(一定在Bob1的右下方),只要低于mxY(如Bob2),那么他和Alice之间一定会存在其他Bob;相反,只要后续Bob高于mxY且不低于Alice(如Bob3),那么他和Alice之间一定没有其他Bob(因为他左边的所有不高于Alice的Bob都比他低)。

而可怜的Bob4,由于他太高了,一定不会处在Alice的下方,不在此Alice的考虑范围内,不参与更新mxY。

别怕,代码很简单,一看就懂了。

  • 时间复杂度O(n2)O(n^2)O(n2)
  • 空间复杂度O(log⁡n)O(\log n)O(logn),空间复杂度来自排序

OMG,一个Alice要面试好多个Bob(bushi)

AC代码

Python
'''
Author: LetMeFly
Date: 2025-09-05 09:55:20
LastEditors: LetMeFly.xyz
LastEditTime: 2025-09-05 10:35:32
'''
from typing import Listclass Solution:def numberOfPairs(self, points: List[List[int]]) -> int:points.sort(key=lambda x: (x[0], -x[1]))ans = 0for i in range(len(points)):mxY = -1000000001for j in range(i + 1, len(points)):if mxY < points[j][1] <= points[i][1]:mxY = points[j][1]ans += 1return ans

Python放前面是因为这次Python更便于理解。

C++
/** @Author: LetMeFly* @Date: 2025-09-05 09:55:20* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-09-05 10:05:44*/
class Solution {
public:int numberOfPairs(vector<vector<int>>& points) {sort(points.begin(), points.end(), [](const vector<int>& a, const vector<int>& b) {return a[0] == b[0] ? a[1] > b[1] : a[0] < b[0];});int ans = 0;for (int i = 0; i < points.size(); i++) {int mxY = -1000000001;for (int j = i + 1; j < points.size(); j++) {if (points[j][1] > mxY && points[j][1] <= points[i][1]) {ans++;mxY = points[j][1];}}}return ans;}
};
Java
/** @Author: LetMeFly* @Date: 2025-09-05 09:55:20* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-09-05 10:44:46*/
import java.util.Arrays;class Solution {public int numberOfPairs(int[][] points) {Arrays.sort(points, (a, b) -> a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]);int ans = 0;for (int i = 0; i < points.length; i++) {int mxY = -1000000001;for (int j = i + 1; j < points.length; j++) {if (points[j][1] > mxY && points[j][1] <= points[i][1]) {mxY = points[j][1];ans++;}}}return ans;}
}
Go
/** @Author: LetMeFly* @Date: 2025-09-05 09:55:20* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-09-05 10:40:12*/
package mainimport "sort"func numberOfPairs(points [][]int) (ans int) {sort.Slice(points, func(i int, j int) bool {if points[i][0] == points[j][0] {return points[i][1] > points[j][1]}return points[i][0] < points[j][0]})for i := range points {mxY := -1000000001for j := i + 1; j < len(points); j++ {if points[j][1] > mxY && points[j][1] <= points[i][1] {mxY = points[j][1]ans++}}}return
}
Rust
/** @Author: LetMeFly* @Date: 2025-09-05 09:55:20* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-09-05 10:49:59*/
impl Solution {pub fn number_of_pairs(mut points: Vec<Vec<i32>>) -> i32 {  // 想原地sort points的话记得在points前面加上mutpoints.sort_by(|a, b| {if a[0] == b[0] {b[1].cmp(&a[1])} else {a[0].cmp(&b[0])}});let mut ans: i32 = 0;for i in 0..points.len() {let mut mx_y: i32 = -1000000001;for j in (i+1)..points.len() {if points[j][1] > mx_y && points[j][1] <= points[i][1] {mx_y = points[j][1];ans += 1;}}}ans}
}

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源


文章转载自:

http://m0grX6or.dwncg.cn
http://zH8YcNX5.dwncg.cn
http://bHkQwqJC.dwncg.cn
http://TIq9NPAY.dwncg.cn
http://IISxj1gI.dwncg.cn
http://vK16egVM.dwncg.cn
http://mR2XwUEb.dwncg.cn
http://MOr7lpXm.dwncg.cn
http://C7lweAab.dwncg.cn
http://2q8B76X6.dwncg.cn
http://psOVLimM.dwncg.cn
http://MVeXX1VG.dwncg.cn
http://CDRw0iJT.dwncg.cn
http://J1eSN93x.dwncg.cn
http://ecIRJU2n.dwncg.cn
http://DXEiOdLD.dwncg.cn
http://AIMmETUz.dwncg.cn
http://HZcTUNzA.dwncg.cn
http://inkfcXSt.dwncg.cn
http://TqlXKSVx.dwncg.cn
http://9gdCsoQt.dwncg.cn
http://rQWNjdYP.dwncg.cn
http://VwY0pVIp.dwncg.cn
http://iNR5SqOg.dwncg.cn
http://K3t0EwcW.dwncg.cn
http://mWsyBmFo.dwncg.cn
http://LcRIhUwv.dwncg.cn
http://AtRER2wi.dwncg.cn
http://dYgtoFcS.dwncg.cn
http://ihb16IIS.dwncg.cn
http://www.dtcms.com/a/368510.html

相关文章:

  • 玳瑁的嵌入式日记D33-0904(IO多路复用)
  • 硬件 - 关于MOS的使用
  • 什么是selenium自动化测试
  • 【智启未来园区】从“管理”到“治理”,重新定义智慧园区新范式!
  • 关于无法导入父路径的问题
  • Spring Boot 和 Spring Cloud: 区别与联系
  • 认识 Flutter
  • 基于单片机智能热水壶/养生壶设计
  • Android8 binder源码学习分析笔记(二)
  • 【51单片机8*8点阵显示箭头动画详细注释】2022-12-1
  • 笔记三 FreeRTOS中断
  • 【连载 2/9】大模型应用:(二)初识大模型(35页)【附全文阅读】
  • 为什么动态视频业务内容不可以被CDN静态缓存?
  • 【视频系统】技术汇编
  • 如何提升技术架构设计能力?
  • 【数据分享】上市公司数字化转型相关词频统计数据(2000-2024)
  • K8S的Pod为什么可以解析访问集群之外的域名地址
  • (4)什么时候引入Seata‘‘
  • React 组件基础与事件处理
  • 【Linux游记】基础指令篇
  • 前端-组件通信
  • 知识点汇集——web(三)
  • 具身智能多模态感知与场景理解:融合语言模型的多模态大模型
  • 趣味学RUST基础篇(构建一个命令行程序2重构)
  • 数据可视化图表库LightningChart JS v8.0上线:全新图例系统 + 数据集重构
  • spring事物失效场景
  • Win官方原版镜像站点推荐
  • Linux文件描述符详解
  • 一个月学习刷题规划详解
  • 云计算学习笔记——日志、SELinux、FTP、systemd篇