剑指offer:数组中的逆序对(Python)

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

解题思路

  1. 这道题在牛客网上,有Python编写正经的解法,会一直提示运行超时。用Java编写时可以通过。
  2. 一般的解题思路可以是直接一个一个比较,但这样比较Low。无视之。

更好一点的是拷贝该数组后对拷贝的数组排序。计算数组中的最小值在原始数组中出现的位置,统计原始数组中最小值前面的个数,之后在原始数组中去掉最小值。重复上述步骤。

代码如下:

def InversePairs(self, data):
    sortData = sorted(data)
    count = 0
    for i in sortData:
        pos = data.index(i)
        count += pos
        data.pop(pos)
    return count

def quick_sort(self, data):
    if len(data) < 2:
        return data
    left = self.quick_sort([i for i in data[1:] if i <= data[0]])
    right = self.quick_sort([j for j in data[1:] if j > data[0]])
    return left + [data[0]] + right

第二种思路:
归并排序的改进版,把数据分成前后两个数组(递归分到每个数组仅有一个数据项)。合并数组,合并时,出现前面的数组值array[i]大于后面数组值array[j]时;则前面数组array[i]~array[mid]都是大于array[j]的,count += mid+1 - i。这个思路来自牛客网中的一位。用Java实现可以通过;但转成原样Python后超时。

代码如下:

import time
import copy
class Solution:
    def InversePairs(self, array):
        if not array:
            return 0
        arrCopy = copy.deepcopy(array)
        return self.InverseRecur(array, arrCopy, 0, len(array)-1)

    def InverseRecur(self, array, arrCopy, start, end):
        if start == end:
            return 0
        mid = (start + end) // 2
        left = self.InverseRecur(array, arrCopy, start, mid)
        right = self.InverseRecur(array, arrCopy, mid+1, end)
        count = 0
        i = mid
        j = end
        locCopy = end
        while i>=start and j > mid:
            if array[i] > array[j]:
                count += j - mid
                arrCopy[locCopy] = array[i]
                locCopy -= 1
                i -= 1
            else:
                arrCopy[locCopy] = array[i]
                locCopy -= 1
                i -= 1

        while i >= start:
            arrCopy[locCopy] = array[i]
            locCopy -= 1
            i -= 1
        while j > mid:
            arrCopy[locCopy] = array[j]
            locCopy -= 1
            j -= 1
        s = start
        while s <= end:
            array[s] = arrCopy[s]
            s += 1
        return left + right + count
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
数组中逆序对在一个数组中,如果前面的数比后面的数大,则这两个数构成一个逆序对。例如,[2, 4, 1, 3, 5]中,(2, 1)、(4, 1)和(4, 3)都是逆序对。 以下是使用Python实现数组中逆序对的代码: ```python def merge(nums, left, mid, right): # 合并两个有序子数组,并计算逆序对数 i = left j = mid + 1 temp = [] count = 0 while i <= mid and j <= right: if nums[i] <= nums[j]: temp.append(nums[i]) i += 1 else: temp.append(nums[j]) j += 1 count += (mid - i + 1) # 计算逆序对数 while i <= mid: temp.append(nums[i]) i += 1 while j <= right: temp.append(nums[j]) j += 1 nums[left:right + 1] = temp return count def merge_sort(nums, left, right): # 归并排序,并返回逆序对数 if left >= right: return 0 mid = (left + right) // 2 count = merge_sort(nums, left, mid) + merge_sort(nums, mid + 1, right) + merge(nums, left, mid, right) return count def reverse_pairs(nums): # 数组中逆序对 if not nums: return 0 return merge_sort(nums, 0, len(nums) - 1) ``` 这里我们使用归并排序来对数组进行排序,并在合并两个有序子数组时计算逆序对数。具体实现时,我们先将数组分成两个子数组,然后分别对两个子数组进行归并排序,并计算两个子数组中逆序对数。然后再将两个有序子数组合并成一个有序数组,并在合并过程中计算逆序对数。最后将得到的逆序对数相加,就是整个数组中逆序对数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值