LeetCode 面试题51. 数组中的逆序对
面试题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. 数组中的逆序对的更多相关文章
- 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对
面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...
- 力扣Leetcode 面试题51. 数组中的逆序对 - 归并排序
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: 0 <= ...
- 《剑指offer》面试题51. 数组中的逆序对
问题描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: ...
- 剑指 Offer 51. 数组中的逆序对 + 归并排序 + 树状数组
剑指 Offer 51. 数组中的逆序对 Offer_51 题目描述 方法一:暴力法(双层循环,超时) package com.walegarrett.offer; /** * @Author Wal ...
- 微软面试题:剑指 Offer 51. 数组中的逆序对 Hard 出现次数:3
题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对. 输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: ...
- 【Java】 剑指offer(51)数组中的逆序对
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成 ...
- MergeSort归并排序和利用归并排序计算出数组中的逆序对
首先先上LeetCode今天的每日一题(面试题51. 数组中的逆序对): 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. ...
- (剑指Offer)面试题36:数组中的逆序对
题目: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 思路: 1.顺序扫描 顺序扫描整个数组,每扫描到一个数字,就将该数 ...
- 【剑指offer】面试题36:数组中的逆序对
题目: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 思路: 归并排序的合并过程.主要是考虑合并两个有序序列时,计算逆序 ...
随机推荐
- 使用charAt()方法查找字符串
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- spring boot 装载自定义yml文件
yml格式的配置文件感觉很人性化,所以想把项目中的.properties都替换成.yml文件,蛋疼的是springboot自1.5以后就把@configurationProperties中的locat ...
- MATLAB——颜色梯度显示
一.colormap函数 figure surf(peaks) k=; mycolor=spring(k); colormap(mycolor); spring是颜色的分类.spring(k)生成k个 ...
- 移动端rem布局实现(vw)
什么是rem?在W3C官网上是这样描述的:“font size of the root element (根元素的字体大小)”.就是说rem是相当于html的,因为网页的默认字体大小是 16px,所以 ...
- Java是未来的第一编程语言吗?
目录 一.前言 二.Java帝国的今天 2.1 依然霸占TIOBE热门编程语言的榜首 2.2 曾经想扼杀Java的微软宣布加入OpenJDK 2.3 Oracle发布开源全栈虚拟机GraalVM 三. ...
- B 蒜头君的树
时间限制 : - MS 空间限制 : - KB 评测说明 : 2s,256m 问题描述 蒜头君有一棵有根树,树的每一边都有边权,蒜头君想知道任意两点间最短距离之和为多少. 另外,由于各种原因,蒜 ...
- B. Food Buying Round #617(递归 + 模拟)
B. Food Buying time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- 非参数估计——核密度估计(Parzen窗)
核密度估计,或Parzen窗,是非参数估计概率密度的一种.比如机器学习中还有K近邻法也是非参估计的一种,不过K近邻通常是用来判别样本类别的,就是把样本空间每个点划分为与其最接近的K个训练抽样中,占比最 ...
- SpringCloud(二)之我学 Ribbon
1.负载均衡 Ribbon 虽然不是显示的配置为一个子项目,但是无论是在 API 网关的转发请求,还是服务之间的调用 Feign ,都是通过 Ribbon 来做负载均衡的. 负载均衡,主要是为了对系统 ...
- springboot-mybatis-oracle学习笔记
前言 最近公司的项目是基于 oracle 数据库的,这里记录下 springboot+mybatis+oracle 的踩坑过程. 开发前准备 环境参数 开发工具:IDEA 基础工具:Maven+JDK ...