【力扣日记】1395 统计作战单位数

题目描述

n 名士兵站成一排。每个士兵都有一个 独一无二 的评分 rating 。

每 3 个士兵可以组成一个作战单位,分组规则如下:

从队伍中选出下标分别为 i、j、k 的 3 名士兵,他们的评分分别为 rating[i]、rating[j]、rating[k]
作战单位需满足: rating[i] < rating[j] < rating[k] 或者 rating[i] > rating[j] > rating[k] ,其中 0 <= i < j < k < n
请你返回按上述条件可以组建的作战单位数量。每个士兵都可以是多个作战单位的一部分。

算法思路

在这里插入图片描述
在提示的指导下:
综合排列组合:

class Solution:
    def numTeams(self, rating: List[int]) -> int:
        res=0
        def helper(ls,k,tp=[]):
            nonlocal res
            if len(tp)==k:
                if tp==sorted(tp)or tp==sorted(tp,reverse=True):
                    res+=1
                return
            for i in range(len(ls)):
                helper(ls[i+1:],3,tp+[ls[i]])
        helper(rating,3)
        return res

执行用时 :5648 ms, 在所有 Python3 提交中击败了5.11%的用户
内存消耗 :13.7 MB, 在所有 Python3 提交中击败了100.00%的用户

就是执行时间惨不忍睹。

把我蠢哭了,直接嵌套循环就好了啊:

class Solution:
    def numTeams(self, rating: List[int]) -> int:
        l=len(rating)
        c=0
        for i in range(l):
            for j in range(i,l):
                for k in range(j,l):
                    if i!=j and j!=k:
                        if rating[i]<rating[j] and rating[j]<rating[k]:
                            c+=1
                        if rating[i]>rating[j] and rating[j]>rating[k]:
                            c+=1
        return c

执行用时 :2924 ms, 在所有 Python3 提交中击败了6.23%的用户

优化:

        l=len(rating)
        c=0
        for i in range(l-2):
            for j in range(i+1,l-1):
                for k in range(j+1,l):
                    
                    if rating[i]<rating[j] and rating[j]<rating[k]:
                        c+=1
                    if rating[i]>rating[j] and rating[j]>rating[k]:
                        c+=1
        return c

执行用时 :1348 ms, 在所有 Python3 提交中击败了35.87%的用户

class Solution:
    def numTeams(self, rating: List[int]) -> int:
        n = len(rating)
        nums = 0
        for i in range(n):
            for j in range(i,n):
                if rating[i] < rating[j]:
                    for k in range(j,n):
                        if rating[j] < rating[k]:
                            nums += 1
                elif rating[i] > rating[j]:
                    for k in range(j,n):
                        if rating[j] > rating[k]:
                            nums += 1
        return nums

执行用时 :592 ms, 在所有 Python3 提交中击败了65.75%的用户

class Solution:
    def numTeams(self, rating: List[int]) -> int:
        n = len(rating)
        leftSmall = [0] * n # leftSmall[i]: nums smaller than nums[i] to the left
        rightSmall = [0] * n # rightSmall[i]: nums smaller than nums[i] to the right
        
        sort = [rating[0]]
        for i in range(1, n):
            leftSmall[i] = bisect.bisect_left(sort, rating[i])
            sort.insert(leftSmall[i], rating[i])
        
        sort = [rating[-1]]
        for i in range(n - 2, -1, -1):
            rightSmall[i] = bisect.bisect_left(sort, rating[i])
            sort.insert(rightSmall[i], rating[i])
        
        ans = 0
        for i in range(1, n - 1):
            ans += leftSmall[i] * (n - 1 - i - rightSmall[i]) + (i - leftSmall[i]) * rightSmall[i]
        return ans

执行用时 :44 ms, 在所有 Python3 提交中击败了99.50%的用户

发布了317 篇原创文章 · 获赞 44 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Heart_for_Ling/article/details/105592953