【Warrior刷题笔记】1996. 游戏中弱角色的数量 【排序+倒序遍历】 详细注释,简单易懂

题目

LC1996.游戏中弱角色的数量

解题思路

此题可以通过排序+倒序遍历处理。
根据题意,一个角色是弱角色的充要条件是存在一个其他角色的攻击力和防御力都严格高于本角色。存在一个即可。那么我们不妨对数组按攻击力从小到大排序,之后对数组倒序遍历,并在遍历过程中实时更新最大防御力,则只要遍历到的当前角色防御力小于最大防御力,该角色就必然是弱角色。因为角色是攻击力从小到大排序的,而我们又是使用倒序的方式遍历,则已遍历过的角色攻击力一定比当前角色高,只需要有一个角色防御力严格高于当前角色,当前角色就是弱角色。
这里存在一个特殊情况,就是角色攻击力可能相同。对于攻击力相同的角色,我们将其合并为一组进行处理,先使用临时变量存储和更新组内最大防御力,而判断组内角色是否是弱角色则使用全局的当前最高防御力进行判断,待这一组处理完毕后,再更新全局当前最大防御力。这样做的理由显而易见,同组角色的攻击力完全相同,不存在严格大于关系,如果处理同组角色的过程中更新全局最高防御力使该最高防御力落在了组内角色上,就会产生误判。
于是有算法:

  1. 计算输入数组大小m,若m==1返回0
  2. 将数组排序,初始化全局最大防御力maxDfs-1,初始化弱角色数ans0
  3. 从计数器i=m-1对数组进行倒序遍历:
  • 若为攻击力非重复元素则直接处理,判断当前角色防御力是否严格小于maxDfs,是则++ans,不是则更新maxDfs;
  • 若为攻击力重复元素则分组处理,初始化角色组指针ki,组内最大防御力tempMaxDfs-1,对所有攻击力与角色i相同的组内元素进行遍历,直至攻击力不等。对每个角色,判断当前角色防御力是否严格小于maxDfs,是则++ans,不是则更新tempMaxDfs。同组角色处理完毕更新maxDfs,更新ik+1
  1. 所有数据处理完毕返回答案ans

代码

class Solution {
public:
    int numberOfWeakCharacters(vector<vector<int>>& properties) {
        int m = properties.size();//计算输入数组的大小
        if(m==1) return 0;//如果大小为1,直接返回0
        sort(properties.begin(),properties.end());//将数组排序
        int maxDfs = -1;//初始化最大防御力为-1
        int ans = 0;//初始化答案为0
        for(int i = m-1; i >= 0; --i){//倒序遍历
            if(i >= 1 && properties[i][0] != properties[i-1][0]){//攻击力非重复元素则直接处理
                if(properties[i][1]<maxDfs) ++ans;//若防御力小于当前最大防御力,则该角色为弱角色
                else maxDfs = properties[i][1];//否则更新最大防御力
            }
            else{//攻击力重复元素按组处理
                int k = i;
                int tempMaxDfs = -1;//组内最大防御力,暂时不同步到maxDfs,因为组内攻击力相同,
                //不存在严格小于关系,不能使用tempDfs判断是否是弱角色
                while(k>=0 && properties[k][0] == properties[i][0]){
                    if(properties[k][1]<maxDfs) ++ans;//若防御力小于组外最大防御力,则该角色为弱角色
                    else tempMaxDfs = tempMaxDfs<properties[k][1] ? properties[k][1] : tempMaxDfs;//否则更新组内防御力
                    --k;
                }
                maxDfs = tempMaxDfs>maxDfs ? tempMaxDfs : maxDfs;//对比组内最大防御力和组外最大防御力,更新maxDfs
                i = ++k;
            }
        }
        return ans;//返回答案
    }
};

复杂度分析

时间复杂度: O(mlogm)m为角色数,排序需要O(mlogm),遍历需要O(m),总时间复杂度O(mlogm)
空间复杂度: O(logm)sort底层大致是快排,需要O(logm)的栈空间。

上一篇:1996年图灵奖--阿米尔·伯努利简介


下一篇:AcWing 1996.打乱字母(贪心,二分)