1996. 游戏中弱角色的数量

多角色游戏中的弱角色判定 —— 解题思路与代码详解

题目描述

在一款多角色的游戏中,每个角色有两个主要属性:攻击(attack)和防御(defense)。给你一个二维整数数组 properties,其中 properties[i] = [attack_i, defense_i] 表示第 i 个角色的属性。

定义“弱角色”如下:

如果存在另一个角色 j,使得 attack_j > attack_idefense_j > defense_i,则角色 i 被认为是弱角色。

请你统计并返回弱角色的数量。


示例

  • 示例 1:
输入: properties = [[5,5],[6,3],[3,6]]
输出: 0
解释: 没有角色的攻击和防御同时被另一角色严格超过。
  • 示例 2:
输入: properties = [[2,2],[3,3]]
输出: 1
解释: 第一个角色被第二个角色的攻击和防御都超过,是弱角色。
  • 示例 3:
输入: properties = [[1,5],[10,4],[4,3]]
输出: 1
解释: 第三个角色被第二个角色的攻击和防御都超过,是弱角色。

解题分析

这道题的核心难点在于如何快速判断对于某个角色 i,是否存在角色 j,满足:

  • attack_j > attack_i
  • defense_j > defense_i

如果直接用两层循环比较,复杂度为 O(n²),当 n 非常大(题目限制最多 10^5)时,会超时。

因此需要借助排序和贪心思想优化。


解题思路

  1. 排序:
    将角色按照攻击值 升序 排列。如果攻击值相同,则按照防御值 降序 排列。
    • 为什么这样排序?
      同攻击值的角色中,防御高的排在前面,这样在后续判断时能避免误判。
      因为“弱角色”要求攻击和防御都严格小于另一个角色,攻击相同的角色之间不存在严格“大于”的关系。
  2. 逆序遍历并维护最大防御值:
    从后向前遍历排序后的数组,维护一个变量 max_defense,表示当前遍历过的角色中最大的防御值。
    • 如果当前角色的防御小于 max_defense,说明在它攻击更大的角色中,有一个角色的防御更大,当前角色就是弱角色。
    • 否则,更新 max_defense

代码实现

from typing import List

class Solution:
    def numberOfWeakCharacters(self, properties: List[List[int]]) -> int:
        # 按攻击升序,防御降序排序
        properties.sort(key=lambda x: (x[0], -x[1]))
        
        max_defense = 0
        weak_count = 0
        
        # 反向遍历,保证攻击值更大
        for attack, defense in reversed(properties):
            if defense < max_defense:
                weak_count += 1  # 当前角色是弱角色
            else:
                max_defense = defense  # 更新最大防御值
        
        return weak_count

复杂度分析

  • 时间复杂度:排序是 O(n log n),遍历一次是 O(n),整体是 O(n log n)。
  • 空间复杂度:排序通常需要 O(log n) 的递归栈空间,算法中额外使用常数空间 O(1)。

代码讲解

  • properties.sort(key=lambda x: (x[0], -x[1]))
    按攻击升序排序,如果攻击值相同,则防御值降序排序。
  • for attack, defense in reversed(properties):
    反向遍历,保证先看到攻击更大的角色。
  • if defense < max_defense:
    当前防御小于已遇到的最大防御,说明存在攻击更大且防御更大的角色,当前角色为弱角色。
  • else: max_defense = defense
    当前防御比最大防御还大,更新最大防御。

示例说明

以示例 [[2,2],[3,3]] 为例:

  • 排序后是 [[2,2],[3,3]],因为本身就满足排序条件。
  • 逆序遍历:
    • 先看 [3,3]max_defense = 0,更新 max_defense = 3
    • 再看 [2,2]2 < max_defense(3),弱角色数 +1。

输出为 1,正确。


总结与思考

  • 这道题考查了二维排序与贪心的结合应用。
  • 关键在于排序策略,防止攻击值相同的角色造成误判。
  • 逆序遍历维护最大防御值,能够在一次遍历中判断角色是否弱。
  • 这类「二维条件筛选」的问题,类似于“skyline问题”或“包裹问题”,可以借鉴排序+扫描的思路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值