zoukankan      html  css  js  c++  java
  • 315. 计算右侧小于当前元素的个数(逆序数)-归并排序-困难

    问题描述

    给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于 nums[i] 的元素的数量。

    示例:

    输入: [5,2,6,1]
    输出: [2,1,1,0]
    解释:
    5 的右侧有 2 个更小的元素 (2 和 1).
    2 的右侧仅有 1 个更小的元素 (1).
    6 的右侧有 1 个更小的元素 (1).
    1 的右侧有 0 个更小的元素.

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self

    解答

    方法1:归并排序

    '''

    归并排序,求逆序数。
    要扩展原数组,加上顺序标记,否则排序之后会丢失顺序。
    时间复杂度:O(nlogn)
    '''
    class Solution(object):
        def countSmaller(self, nums):
            if not nums:
                return []
            def merge(list1, list2, index):
                arr = []
                len1 = len(list1)
                len2 = len(list2)
                i = 0
                j = 0
                while i < len1 and j < len2:
                    if list1[i][index] > list2[j][index]:
                        arr.append(list2[j])
                        j += 1
                    else:
                        if index == 0:
                            list1[i][2] += j
                        arr.append(list1[i])
                        i += 1
                while i < len1:
                    if index == 0:
                        list1[i][2] += j
                    arr.append(list1[i])
                    i += 1
                while j < len2:
                    arr.append(list2[j])
                    j += 1
                return arr
            def merg_sort(a, index):
                len_a = len(a)
                if len_a <= 1:
                    return a
                list2 = merg_sort(a[len_a/2:],index)
                list1 = merg_sort(a[:len_a/2],index)
                return merge(list1, list2, index)
            temp = []
            len_nums = len(nums)
            for i in range(0,len_nums):
                temp.append([nums[i],i,0])
            temp = merg_sort(temp,0)
            temp = merg_sort(temp,1)
            return zip(*temp)[2]

    方法二:二分查找,查找到的索引就是逆序数了,再将数字插入有序数组。

    '''
    二分查找,时间复杂度也是O(nlogn)
    '''
    class Solution(object):
        def countSmaller(self, nums):
            result = []
            arr = []
            nums.reverse()
            for i in nums:
                index = bisect.bisect_left(arr, i) #这是二分查找,返回的是插入的位置
                arr.insert(index, i) #插叙有序数组arr
                result.append(index) #index就是逆序数了
            result.reverse()
            return result
  • 相关阅读:
    实例教学在MySQL中若何导出整个数据库
    在Linux下Turbomail简易快捷的装置方式
    Fedora下编译mitscheme
    Fedora 9可以不敌RedHat 9光辉
    实用伎俩:Ubuntu Linux 8.04设置与优化
    Linux下给WordPress建设伪静态
    红旗桌面版本最新使用要领和题目问题解答100例5
    知识管理系统红旗Linux/KM.Center
    python 虚拟环境的安装
    python 闭包
  • 原文地址:https://www.cnblogs.com/xxxxxiaochuan/p/13246068.html
Copyright © 2011-2022 走看看