1996. 游戏中弱角色的数量

1996. 游戏中弱角色的数量

难度中等73收藏分享切换为英文接收动态反馈

你正在参加一个多角色游戏,每个角色都有两个主要属性:攻击 和 防御 。给你一个二维整数数组 properties ,其中 properties[i] = [attacki, defensei] 表示游戏中第 i 个角色的属性。

如果存在一个其他角色的攻击和防御等级 都严格高于 该角色的攻击和防御等级,则认为该角色为 弱角色 。更正式地,如果认为角色 i 弱于 存在的另一个角色 j ,那么 attack[j] > attack[i] 且 defense[j] > defense[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
解释:第三个角色是弱角色,因为第二个角色的攻击和防御严格大于该角色。

提示:

  • 2 <= properties.length <= 10^5
  • properties[i].length == 2
  • 1 <= attack[i], defense[i] <= 10^5

思路一:最直观的思路当然是用O(n^2)的复杂度枚举出所有的元素对,然后进行统计。but,本题关注的是有多少个元素是弱元素,如果某一个元素在多个元素对情况下可以被多次作为弱元素也只算做一次,因此没判断出一个就可以从候选集合中剔除。

思路二:题目要求的条件是attack[j] > attack[i] 且 defense[j] > defense[i] 这两个,那我们可以先针对attack属性降序排序,然后我们只需要考虑defense属性就可以了。

先来看attack无重复的情形,由于已经排序过,因此有attack[i] > attack[j],任意的i只要满足i < j;也就是说我们已经可以不考虑attack属性了,那么为了能够尽可能的将properties[j]作为弱元素,我们需要在所有的i < j的中选出最大的max_defense属性,那么只要这个max_defense > properties[j][1],那么properties就可以作为弱元素

那么attack重复怎么办呢?我们上面的逻辑对于attack不相同的元素来说是正确的,但是对于拥有相同的attack的元素来说可能会计算错误,例如

(10, 8) - (10, 3):这个数对实际上不应该提供对答案的贡献,但是因为上面的逻辑默认认为前一个的attack大于后面的,所以只会看defense属性的大小,所以按照上面的逻辑会对答案增加贡献1。然而实际上,对于attack属性相同的情况,实际上本身就已经不满足attack严格大于了,因此attack相同的组内不应该贡献任何答案,那么为了避免attack相同的元素对答案产生贡献,我们在排序的时候,对attack属性相同的元素可以直接按照defense逆序排序,这样attack属性相同的元素对将不会产生任何贡献。

class Solution {
public:

    static bool cmp(vector<int>& A, vector<int>& B){
        return A[0] > B[0] || (A[0] == B[0] && A[1] < B[1]);
    }

    int numberOfWeakCharacters(vector<vector<int>>& properties) {
        int n = properties.size(), ans = 0, max_attack;
        sort(properties.begin(), properties.end(), cmp);
        max_attack = properties[0][1];
        for(int i = 1; i < n; ++ i){
            if(max_attack > properties[i][1]){
                ++ ans;
            }else{
                max_attack = properties[i][1];
            }
        }
        return ans;
    }
};

注:在设计cmp函数的时候,对于C++来说,vector的=重载的是拷贝行为,改成引用可以节省大量时间(不容易被卡)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值