LeetCode算法-1395. 统计作战单位数[medium]

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

在这里插入图片描述

可以查看官方解析,很清楚哦!
在这道题中,学到了要学会分析样例数据的规律,有助于找到优化算法的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值