返回

释放路飞的力量:掌握 LeetCode 315,征服右侧元素计数算法!

前端

在这片浩瀚的算法海洋中,我们今天将踏上征服 LeetCode 315 的征途。这道看似简单的题目,蕴藏着深奥的计数算法奥秘。系紧安全带,跟随我一起释放路飞的力量,在这个算法世界中尽情驰骋!

问题的烽火

给定一个整数数组 nums,我们肩负的使命是计算出一个新数组 counts。而 counts 中每个元素 counts[i] 的使命,便是统计 nums[i] 右侧比它小的元素数量。

这就好比路飞在伟大航路上的征途,他需要不断超越比他弱小的对手,累积胜利的勋章。而 counts 中的每个元素,就是路飞在这个计数战场上斩获的勋章数。

算法的航线

算法 1:暴力解法

如同路飞初出茅庐时的蛮力战斗,暴力解法简单直接。我们逐个遍历数组,对于每个元素 nums[i],我们再遍历其右侧的元素,统计出比它小的数量。

def countSmaller(nums):
    counts = [0] * len(nums)
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):
            if nums[j] < nums[i]:
                counts[i] += 1
    return counts

算法 2:归并排序解法

路飞在修行中不断精进,算法也随之蜕变。归并排序解法如同一场优雅的战斗,将数组一分为二,征服后再合并。

def countSmaller(nums):
    def merge(left, right):
        merged = []
        count = 0
        l, r = 0, 0
        while l < len(left) and r < len(right):
            if left[l] > right[r]:
                count += len(left) - l
                merged.append(right[r])
                r += 1
            else:
                merged.append(left[l])
                l += 1
        merged.extend(left[l:])
        merged.extend(right[r:])
        return merged, count

    def merge_sort(nums):
        if len(nums) <= 1:
            return nums, 0

        mid = len(nums) // 2
        left, left_count = merge_sort(nums[:mid])
        right, right_count = merge_sort(nums[mid:])

        merged, count = merge(left, right)
        return merged, left_count + right_count + count

    return merge_sort(nums)[1]

胜利的号角

通过这道题目,我们领略了算法世界中的巧妙与严谨。无论是暴力的正面冲锋,还是归并排序的优雅征服,都为路飞的成长之旅增添了浓墨重彩的一笔。

愿你也能在这个算法海洋中乘风破浪,成为一名真正的算法大师!