zoukankan      html  css  js  c++  java
  • 51. 数组中的逆序对

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

    示例 1:

    输入: [7,5,6,4]
    输出: 5

    方法1:暴力求解
    使用简单的循环判断,我们的思路是顺序扫描整个数组,每扫到一个数字,逐个比较该数自和它后面的数字大小
    这种方法时间复杂度为O(n**2),空间复杂度O(1)
    这种方法跑不通oj,时间复杂度很高

    class Solution:
        def reversePairs(self, nums: List[int]) -> int:
            length = len(nums)
            if length == 0 or length==1:
                return 0
            res = 0
            for i in range(length-1):
                count = 0
                for j in range(i,length):
                    if nums[i]>nums[j]:
                        count+=1
                res += count
            return res

    方法2:基于归并排序的统计

     下面我们这样来思考:[7,5,6,4]

    1.先把数组分成两个部分[7,5],[6,4],在继续分割成[[7],[5]],[[6],[4]]两个组;
    2.接着进行合并,先合并[[7],[5]],由于7>5,在这个组内存在一个逆序排列,根据由小到大排序得到[5,7];同理对[[6],[4]]进行同样的操作,得到[4,6],同样也存在一个逆序对;
    3.下面进行组间的合并s1=[5,7],s2=[4,6],此时我们需要需要一个辅助数组s来存储排序好的数组,我们设置两个指针分别指向s1和s2的尾部,当前指向的数字为7和6,由于这两个数组都是排好序的,所以7会大于s2中的所有数字,即与7能组成逆序对的个数为s2数组的长度,然后将7放入s的末尾,再比较5和6,5<6,不存在逆序对,将6放入s中,此时s=[6,7],再次比较5和4,5>4,存在逆序对,逆序对的数目等于1,将5放入s,将4放入s;
    4.如此下去,可以发现上面的过程就是归并排序的过程,只需简单的加入统计逆序对变量即可;

    class Solution(object):
        def reversePairs(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            result = [0]
            def Merge_sort(s):
                n = len(s)
                if n < 2:
                    return
                mid = n // 2
                s1 = s[0:mid]
                s2 = s[mid:n]
                Merge_sort(s1)
                Merge_sort(s2)
                Merge(s1,s2,s)
    
            def Merge(s1,s2,s):
                len_s1 = len(s1) - 1
                len_s2 = len(s2) - 1
                temp = len(s) - 1
                
                while len_s1 >=0 and len_s2 >= 0:
                    if s1[len_s1] > s2[len_s2]:
                        s[temp] = s1[len_s1]
                        result[0] += len_s2 + 1
                        len_s1 -= 1
                        temp -= 1
                    else:
                        s[temp] = s2[len_s2]
                        len_s2 -= 1
                        temp -= 1
                        
                while len_s1 >= 0:
                    s[temp] = s1[len_s1]
                    len_s1 -= 1
                    temp -= 1
                while len_s2 >= 0:
                    s[temp] = s2[len_s2]
                    temp -= 1
                    len_s2 -= 1
    
            Merge_sort(nums)
            return result[0]

     方法3:二分查找与插入

    class Solution:
        def reversePairs(self, nums: List[int]) -> int:
            cnt, tmp = 0, []
            for num in nums[::-1]:
                cnt += bisect_left(tmp, num)#二分插入,计算已有列表(后面的先插入)比num小的数字
                insort(tmp, num)
            return cnt
  • 相关阅读:
    多态
    扩展方法
    git 新账户链接新仓库地址
    获取数据类型
    解构赋值
    var let const 无关键字定义变量
    http
    onmouseover、onmouseout、onmouseenter、onmouseleave
    setInterval、setTimeout、requestAnimationFrame
    vue的prop父子组件传值
  • 原文地址:https://www.cnblogs.com/USTC-ZCC/p/12603769.html
Copyright © 2011-2022 走看看