本文涉及的基础知识点
排序
C++算法:滑动窗口及双指针总结
本题其它解法
【C++单调栈 排序】1996. 游戏中弱角色的数量|1996
LeetCode1996. 游戏中弱角色的数量
你正在参加一个多角色游戏,每个角色都有两个主要属性:攻击 和 防御 。给你一个二维整数数组 properties ,其中 properties[i] = [attacki, defensei] 表示游戏中第 i 个角色的属性。
如果存在一个其他角色的攻击和防御等级 都严格高于 该角色的攻击和防御等级,则认为该角色为 弱角色 。更正式地,如果认为角色 i 弱于 存在的另一个角色 j ,那么 attackj > attacki 且 defensej > defensei 。
返回 弱角色 的数量。
示例 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 <= 105
properties[i].length == 2
1 <= attacki, defensei <= 105
排序+双指针
i从大到小处理第i个角色,attack[j] > attack[i],且j最小。
maxDefen 是defen[j…n-1]的最大值。
由于attack是升序,如果attack[j] > attack[i]。
性质一:x > j ,则attack[x] > attack[i]。
性质二:x < j ,attack[j-1] <= attack[i],则attack[x] <= attack[j]。
根据性质一和性质二:有且只有 [j…n-1]的攻击大于i。
性质三:x < i → \rightarrow → attack[x] < attack[j]。 ⟺ \iff ⟺ 随着i变小j,不会被移除。
时间复杂度:O(nlogn) 瓶颈在排序
代码
核心代码
class Solution {
public:
int numberOfWeakCharacters(vector<vector<int>>& properties) {
sort(properties.begin(), properties.end());
int maxD = 0;
const int N = properties.size();
int ans = 0;
for (int i = N - 1, j = N; i >= 0; i--) {
while (j && (properties[j-1][0] > properties[i][0])) {
maxD = max(maxD, properties[--j][1]);
}
ans += properties[i][1] < maxD;
}
return ans;
}
};
单元测试
vector<vector<int>> properties;
TEST_METHOD(TestMethod11)
{
properties = { {5,5},{6,3},{3,6} };
auto res = Solution().numberOfWeakCharacters(properties);
AssertEx(0, res);
}
TEST_METHOD(TestMethod12)
{
properties = { {2,2},{3,3} };
auto res = Solution().numberOfWeakCharacters(properties);
AssertEx(1, res);
}
TEST_METHOD(TestMethod13)
{
properties = { {1,5},{10,4},{4,3} };
auto res = Solution().numberOfWeakCharacters(properties);
AssertEx(1, res);
}
TEST_METHOD(TestMethod14)
{
properties = { {1,1},{2,1},{2,2},{1,2} };
auto res = Solution().numberOfWeakCharacters(properties);
AssertEx(1, res);
}