leetcode刷题_(剑指offer_归并排序)_51寻找逆序对

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

示例 1:

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

限制:

0 <= 数组长度 <= 50000

解答:
根据之前的经验可知 此题使用归并排序解答。
1 归并使用双封闭的二分[ l ,m ] [ m+1 , r ],即能取到最右端的值,初始带入r = len-1.
2 归并终止条件为 l<r, 终止点位l=r。
3 排序中的while循环终止条件为 i<=len and j<=len,因为经历过一次比较以后,i 或者j自增,到达了i或者j数组的边界,这时index是超出数组的,但是仍然需要进行一轮循环,将最后的部分直接extend上。
4 排序中 在满足 arr_l[i] > arr_r[j]的地方进行**+左边现存数的个数**,即为len-i。当达到边界时不需要加和 因为之前已经全部计数。
5 记住 i j到达边界时的break!

代码:

class Solution:
    def reversePairs(self, nums) -> int:
        global res
        res = 0
        self.merge(nums, 0, len(nums) - 1)
        return res

    def merge(self, arr, l, r):
        if l < r:
            mid = (l + r) // 2
            self.merge(arr, l, mid)
            self.merge(arr, mid + 1, r)
            self.sort(arr, l, r,mid)

    def sort(self, arr, l, r, m):
        arr_l = arr[l:m + 1]
        arr_r = arr[m + 1:r + 1]
        new = []
        i = 0
        j = 0
        #print(arr_l,arr_r,l,m,m+1,r)
        while i <= m - l + 1 and j <= r - m:
            #print(i,j,m-l+1,r-m+1)
            global res
            if i == m - l+1:
                new.extend(arr_r[j:])
                break
            elif j == r - m:
                new.extend(arr_l[i:])
                # global res
                #print(m-l+1-i,'1111111')
                #res += (m - l - i)
                break
            elif arr_l[i] > arr_r[j]:
                new.append(arr_r[j])
                #print(j+1,'2222222222')
                res +=  (m-l-i+1)
                j += 1
            else:
                new.append(arr_l[i])
                i += 1
        #print(res,'##')
        arr[l:r + 1] = new

TIPS:
1 归并二分的 双闭区间 l<r终止条件
2 while循环的 and 以及 均为<=len
3 边界处的break
4 逆序对count的思想

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值