题目描述:
你正在参加一个多角色游戏,每个角色都有两个主要属性:攻击 和 防御 。给你一个二维整数数组properties,其中properties[i] = [attack i, defense i] 表示游戏中第 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
解释:第一个角色是弱角色,因为第二个角色的攻击和防御严格大于该角色。
提示:
- 2 <= properties.length <= 100000
- properties[i].length == 2
- 1 <= attack i, defense i <= 100000
解题步骤:
我们针对每个角色需要判断是否存在一个攻击值和防御值都高于它的角色,从而确定该角色是否为弱角色。
- 可以将每个角色按照攻击力从大到小进行排序(攻击力相同的角色是挨在一块的)
- 针对具有相同攻击力的角色,按照防御力在组内按照防御力值从小到大排序
- 遍历数组
- 当攻击力不同的时候,当当前的防御值小于前面角色的防御值的时候,此时该角色一定为弱角色
- 当攻击力相同的时候,在相同攻击力的组内,是不存在当前的防御值小于前面角色防御值的情况
单调栈和排序思路都为上面所述
代码:
排序:
class Solution {
public int numberOfWeakCharacters(int[][] properties) {
Arrays.sort(properties, (o1, o2) -> {
return o1[0] == o2[0] ? (o1[1] - o2[1]) : (o2[0] - o1[0]);
});
int maxDef = 0;
int ans = 0;
for (int[] p : properties) {
//防御值小于之前的角色防御值,只有攻击力不同的时候才会出现此情况
if (p[1] < maxDef) {
ans++;
} else {
//更新前面角色中的最大值
maxDef = p[1];
}
}
return ans;
}
}
复杂度分析:
时间复杂度:O(n log n),其中 n 为数组的长度。排序的时间复杂度为 O(n log n),遍历数组的时间为 O(n),总的时间复杂度为 O(n log n)。
空间复杂度:O(log n),其中 n 为数组的长度。排序时使用的栈空间为 O(log n)。
单调栈:
class Solution {
public int numberOfWeakCharacters(int[][] properties) {
Arrays.sort(properties, (o1, o2) -> {
return o1[0] == o2[0] ? (o2[1] - o1[1]) : (o1[0] - o2[0]);
});
int ans = 0;
Deque<Integer> st = new ArrayDeque<Integer>();
for (int[] p : properties) {
while (!st.isEmpty() && st.peek() < p[1]) {
st.pop();
ans++;
}
st.push(p[1]);
}
return ans;
}
}
复杂度分析:
时间复杂度:O(n log n)。
空间复杂度:O(n)。