0%

[Leetcode]1395. Count Number of Teams

题目描述

There are n soldiers standing in a line. Each soldier is assigned a unique rating value.

You have to form a team of 3 soldiers amongst them under the following rules:

Choose 3 soldiers with index (i, j, k) with rating (rating[i], rating[j], rating[k]).
A team is valid if: (rating[i] < rating[j] < rating[k]) or (rating[i] > rating[j] > rating[k]) where (0 <= i < j < k < n).
Return the number of teams you can form given the conditions. (soldiers can be part of multiple teams).

例子

例子 1

Input: rating = [2,5,3,4,1]
Output: 3
Explanation: We can form three teams given the conditions. (2,3,4), (5,4,1), (5,3,1).

例子 2

Input: rating = [2,1,3]
Output: 0
Explanation: We can’t form any team given the conditions.

例子 3

Input: rating = [1,2,3,4]
Output: 4

限制条件

  • n == rating.length
  • 1 <= n <= 200
  • 1 <= rating[i] <= 10^5

解题思路

方法一

看数据规模在 200 以下首先可以想到用暴力解法,直接用三层 for 循环遍历所有的可能性求可能的解;另外我首先想的方法是用回溯+剪枝,但是在这道题里面每个组规定的组员是固定,而且只有三个。在这种情况下用三层for循环能够避免递归产生的开销,更加合适;代码比较简单就不写了。

  • 时间复杂度: O(n^3)
  • 空间复杂度: O(1)

方法二

这道题还有一种比较巧妙的解法,我是参考花花酱的题解视频写出来的,这里分享一下。首先假设我们选中在 i 位置的士兵作为队伍的中间人;那么对他而言,我们首先找出他左边排名比他小的,假设有 l 个;右边排名比他大的,假设有 r 个。那么有:

  • 对于升序的情况,组合有: l * r
  • 对于逆序的情况,左边有 i - l 个,右边有 N - 1 - l 个,所以有 (i - l) * (N - 1 - l)
  • 最后相加一个

上面是针对一个士兵的,那么我们遍历一遍取所有士兵作为中间值就可以求得总的解数量,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public:
int numTeams(vector<int>& rating) {
int counts = 0;

for (int i = 0; i < rating.size(); i++) {
int left = 0;
int right = 0;

for (int j = 0; j < rating.size(); j++) {
if (j < i && rating[j] < rating[i]) {
left++;
}
if (j > i && rating[j] > rating[i]) {
right++;
}

// we have left rating is less than rating[i] and right ratings larger than rating[i]

}
counts += left * right;
counts += (i - left) * (rating.size() - 1 - i - right);
}

return counts;
}
};
  • 时间复杂度: O(n^2)
  • 空间复杂度: O(1)