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).
Example 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).
Example 2:
Input: rating = [2,1,3]
Output: 0
Explanation: We can’t form any team given the conditions.
Example 3:
Input: rating = [1,2,3,4]
Output: 4
Constraints:
n == rating.length
1 <= n <= 200
1 <= rating[i] <= 10^5
思路:该题目就是从给定的序列中找出三个有大小顺序的子序列。
- 简单暴力:三层循环,给定i,j,k三个位置,直接判断是否存在
a[i]<a[j]<a[k]
或者a[i]>a[j]>a[k]
;时间复杂度太高了( O ( N 3 ) O(N^3) O(N3)),空间复杂度 O ( 1 ) O(1) O(1)
code:
class Solution:
def numTeams(self, rating: List[int]) -> int:
count = 0
for i in range(len(rating)):
for j in range(i+1, len(rating)):
for k in range(j+1, len(rating)):
if (rating[i] < rating[j] and rating[j] < rating[k]) or (rating[i] > rating[j] and rating[j] > rating[k]):
count += 1
return count
- 观察样例可以发现:以中间点为参考点,在原list中查找中间点的位置,在该位置的左侧,所有比该元素小的数放入一个集合,比他大的元素放入一个集合,右侧同理。可以发现,任意从左边小集合、右边大集合中抽出一个,或者任意从左边大集合、又变小集合中抽出一个,都可以和中间元素组成一个有序的三元组。所以,我们只需要将四个集合中的元素进行计数,计算出所有的组合数即可。
- 时间复杂度 O ( N 2 ) O(N^2) O(N2)
class Solution:
def numTeams(self, rating: List[int]) -> int:
count = 0
for j in range(1, len(rating)-1):
lsmall = rsmall = lbig = rbig = 0
for i in range(j):
if rating[i] < rating[j]:
lsmall += 1
elif rating[i] > rating[j]:
lbig += 1
for k in range(j + 1,len(rating)):
if rating[j] < rating[k]:
rbig += 1
elif rating[j] > rating[k]:
rsmall += 1
count += lsmall * rbig + lbig * rsmall
return count
可以查看官方解析,很清楚哦!
在这道题中,学到了要学会分析样例数据的规律,有助于找到优化算法的方法。