面试题51. 数组中的逆序对


题目来源:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/

题目


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

示例 1:

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

解题思路


思路:归并排序

归并排序使用了分治的思想,这个过程需要使用递归来实现。在分治算法递归实现中,每层递归会涉及三个步骤:

  • 分解:将原问题分解为一系列子问题;
  • 解决:递归求解各个子问题,若子问题足够小,直接求解;
  • 合并:将子问题的结果合并为原问题。

在本题当中,

  • 分解:假设区间为 [left, right],令 mid = [(left + right) / 2],将 [left, right] 分成 [left, mid][mid + 1, right]
  • 解决:使用递归排序两个子序列;
  • 合并:将已经排好的子序列 [left, mid][mid + 1, right] 合并

题目中要求返回数组构成逆序对的总数。逆序对:即是前面的一个数字大于后面的数字,那么这两个数字可以构成一个逆序对。

具体思想参考代码。

代码实现


class Solution:
def reversePairs(self, nums: List[int]) -> int:
n = len(nums)
if n < 2:
return 0
# 辅助数组,用于归并
temp = [0] * n
return self.count_invs(nums, 0, n - 1, temp) def count_invs(self, nums, left, right, temp):
if left == right:
return 0 mid = (left + right) // 2
left_pairs = self.count_invs(nums, left, mid, temp)
right_pairs = self.count_invs(nums, mid+1, right, temp)
# 这里表示已经排序好,并且已经计算左右两部分未排序前的逆序对
invs_pairs = left_pairs + right_pairs if nums[mid] < nums[mid + 1]:
# 这个时候表示都是顺序排序,不用计算两个区间交叉的逆序对,直接返回
return invs_pairs # 这里计算区间交叉的逆序对
invs_cross_pairs = self.merge_count(nums, left, mid, right, temp) return invs_pairs + invs_cross_pairs def merge_count(self, nums, left, mid, right, temp):
# 现在两个区间都是有序的
# 合并计算此时区间交叉的逆序对个数
# 复制原数组到辅助数组
for i in range(left, right + 1):
temp[i] = nums[i] p = left
q = mid + 1
ans = 0
for i in range(left, right + 1):
# 这里归并剩余的部分
if p > mid:
nums[i] = temp[q]
q += 1
elif q > right:
nums[i] = temp[p]
p += 1
elif temp[p] <= temp[q]:
# 这个时候,前面部分区间的元素出列
# 因为 p 对应的元素,比 q 对应的元素小
# 那么 p 对应的元素一定比 q 对应元素后面的元素都小
# 所以这个时候不统计逆序对,p 往前移动
nums[i] = temp[p]
p += 1
else:
# 这种属于相反的情况
# p 对应的元素比 q 对应的元素大,
# 那么 p 对应的元素后面的元素一定更大
# 所以,元素出列同时统计逆序对
# 这个时候,数组位置 p 到该区间末尾有多少个元素就有多少个逆序对,即是 mid - p + 1
nums[i] = temp[q]
q += 1
ans += (mid - p + 1) return ans

实现结果



以上就是使用归并排序的思想,解决《面试题51. 数组中的逆序对》问题的主要内容。


欢迎关注微信公众号《书所集录》

LeetCode 面试题51. 数组中的逆序对的更多相关文章

  1. 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对

    面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...

  2. 力扣Leetcode 面试题51. 数组中的逆序对 - 归并排序

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: 0 <= ...

  3. 《剑指offer》面试题51. 数组中的逆序对

    问题描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5   限制: ...

  4. 剑指 Offer 51. 数组中的逆序对 + 归并排序 + 树状数组

    剑指 Offer 51. 数组中的逆序对 Offer_51 题目描述 方法一:暴力法(双层循环,超时) package com.walegarrett.offer; /** * @Author Wal ...

  5. 微软面试题:剑指 Offer 51. 数组中的逆序对 Hard 出现次数:3

    题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对. 输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: ...

  6. 【Java】 剑指offer(51)数组中的逆序对

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成 ...

  7. MergeSort归并排序和利用归并排序计算出数组中的逆序对

    首先先上LeetCode今天的每日一题(面试题51. 数组中的逆序对): 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. ...

  8. (剑指Offer)面试题36:数组中的逆序对

    题目: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 思路: 1.顺序扫描 顺序扫描整个数组,每扫描到一个数字,就将该数 ...

  9. 【剑指offer】面试题36:数组中的逆序对

    题目: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 思路: 归并排序的合并过程.主要是考虑合并两个有序序列时,计算逆序 ...

随机推荐

  1. poj - 2096 概率dp (找bug)

    题意:一个人一天只能找1个bug ,这个bug属于s个子系统中的某一个子系统,属于n种bug 中的某一种 ,求 这个人找出n种bug ,并且s个系统都bug的期望 (每个系统的一定可以找出bug) 一 ...

  2. Thread --三大特性 原子性,可见性,有序性

    原子性.可见性.有序性 什么是原子性 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行. 一个很经典的例子就是银行账户转账问题: 比如从账户A向账户B转1000元, ...

  3. 关于泛型数据结构中OrderBy的使用

    形如, 1) ICollection<ImageInfo> imageInfos = new List<ImageInfoDTO>(); imageInfos = imageI ...

  4. A 组队参赛

    时间限制 : - MS   空间限制 : - KB  评测说明 : 1s,256m 问题描述 一年一度的ioiAKer大赛即将来临,何老板打算让信竞队的同学们组队参赛.信竞队共n名队员,他们的CF积分 ...

  5. B 方块消消乐

    时间限制 : - MS   空间限制 : - KB  评测说明 : 1s,128m 问题描述 何老板在玩一款消消乐游戏,游戏虽然简单,何老板仍旧乐此不疲.游戏一开始有n个边长为1的方块叠成一个高为n的 ...

  6. php 直接跳出嵌套循环

    break 结束当前 for,foreach,while,do-while 或者 switch 结构的执行. break 可以接受一个可选的数字参数来决定跳出几重循环. <?php $arr = ...

  7. flask-类视图

    flask-类视图 标准类视图 from flask import Flask, render_template, views, jsonify app = Flask(__name__) class ...

  8. spark模型运行时无法连接摸个excutors异常org.apache.spark.shuffle.FetchFailedException: Failed to connect to xxxx/xx.xx.xx.xx:xxxx

    error:org.apache.spark.shuffle.FetchFailedException: Failed to connect to xxxx/xx.xx.xx.xx:xxxx 定位来定 ...

  9. 测量C++程序运行时间

    有个很奇怪的现象,我自认为写得好的文章阅读量只有一百多,随手写的却有一千多--要么是胡搞,要么是比较浅显.纵观博客园里众多阅读过万的文章,若非绝世之作,则必为介绍入门级知识的短文.为了让我的十八线博客 ...

  10. mysql 单机多实例配置

    如果你想在一台机器上进行主从配置实验,本篇可以帮助你实现愿望 [client] #password = your_password port = 3306 socket = /tmp/mysql.so ...