题目描述

  • 多说无益~直接冲代码吧!

思路 && 代码

1. 暴力 O(n2n^2n2)

  • 乍一看这题目,很难不直接用暴力法冲一冲(也就双层循环的事)
  • 但是不出意料地超时啦~想一想,O(n2n^2n2)会超时,那么我们就试着思考怎么降低时间复杂度到O(nlogn)吧!(还是不行的话,就再去思考O(n)的方法,循序渐进~)
  • 于是,分治的思路就跃然于纸上了~
class Solution {public int reversePairs(int[] nums) {// 暴力int res = 0;int len = nums.length;for(int i = len - 1; i > 0; i--) {for(int j = i - 1; j >= 0; j--) {if(nums[j] > nums[i]) {res++;}}}return res;}
}

2. 归并排序法(分治O(nlogn))

  • 总体框架应该是和归并排序一样的
  • 从头思考,如果采用分治的方法进行二分,需要有怎样的考虑?
    1. 当前递归层的结果,首先应该是左半边内部的结果 + 右半边内部的结果
    2. 然后,应该再对左半边与右半边的联系进行处理
  • 为什么要排序?
    1. 首先,我们通过二分递归的形式,占用了O(logn)的复杂度
    2. 然后,我们需要使用剩下的O(n)复杂度,完成剩下的步骤
    3. 而排序,占用了O(n)复杂度,同时实现了剩下的步骤
    4. 左半边排序、右半边排序后,并不会影响左右半边直接的联系,也就是无后效性
  • 合并操作
    1. 维护 lowIndex,用于记录插入左半边值后,新增的逆序对。
    2. 插入左半边值后,增加的逆序对 = 已经插入的右边值个数
    3. 注意:左半边当前值、右半边当前值相同的情况,选择插入左半边当前值,这是为了保证正确性。(可以写个例子考虑一下就知道原因了~)
class Solution {public int reversePairs(int[] nums) {return mergeSort(nums, 0, nums.length - 1);}public int mergeSort(int[] nums, int left, int right) {if(left >= right) {return 0;}// 1. 二分,先获取【合并前局部逆序对】总数int mid = (left + right) / 2;int res = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right);// 2. 合并处理int i = left, j = mid + 1;int[] arr = new int[right - left + 1];// 用于处理相等情况int lowIndex = 0;for(int k = 0; k < arr.length; k++) {if(i > mid){arr[k] = nums[j++];}else if(j > right || nums[i] <= nums[j]) {res += lowIndex;arr[k] = nums[i++];}else if(nums[i] > nums[j]){lowIndex++;arr[k] = nums[j++];}}// 把排序数组赋予原数组for(i = left; i <= right; i++) {nums[i] = arr[i - left];}return res;}
}

二刷

  • 归并排序的思想可太能套用了!
class Solution {// 归并排序public int reversePairs(int[] nums) {return mergeSort(nums, 0, nums.length - 1);}int mergeSort(int[] nums, int left, int right) {if(left >= right) {return 0;}int mid = (left + right) / 2;int res = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right);int[] arr = new int[right - left + 1];int first = left, second = mid + 1;for(int i = 0; i < arr.length; i++) {if(first > mid) {arr[i] = nums[second++];}else if(second > right || nums[first] <= nums[second]) {arr[i] = nums[first++];res += second - mid - 1;}else if(nums[second] < nums[first]) {arr[i] = nums[second++];}}for(int i = 0; i < arr.length; i++) {nums[left + i] = arr[i];}return res;}
}

【LeetCode笔记】剑指Offer 51. 数组中的逆序对(Java、分治)相关推荐

  1. 【LeetCode】剑指 Offer 51. 数组中的逆序对

    [LeetCode]剑指 Offer 51. 数组中的逆序对 文章目录 [LeetCode]剑指 Offer 51. 数组中的逆序对 package offer;public class Soluti ...

  2. 剑指 Offer 51. 数组中的逆序对(归并排序做法)

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

  3. 【剑指offer】数组中的逆序对

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/27520535 转载请注明出处:http:// ...

  4. 剑指offer:数组中的逆序对

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

  5. 剑指offer之数组中的逆序对

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

  6. 《剑指offer》-- 数组中的逆序对、最小的K个数、从1到n整数中1出现的次数、正则表达式匹配、数值的整数次方

    一.数组中的逆序对: 1.题目: 数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出 ...

  7. 剑指offer T51数组中的逆序对

    case1:暴力法 class Solution {/*case1:暴力法*/public int reversePairs(int[] nums) {int len = nums.length;if ...

  8. 【LeetCode】剑指 Offer 56. 数组中数字出现的次数

    [LeetCode]剑指 Offer 56. 数组中数字出现的次数 文章目录 [LeetCode]剑指 Offer 56. 数组中数字出现的次数 package offer;import java.u ...

  9. 【LeetCode】剑指 Offer 39. 数组中出现次数超过一半的数字

    [LeetCode]剑指 Offer 39. 数组中出现次数超过一半的数字 文章目录 [LeetCode]剑指 Offer 39. 数组中出现次数超过一半的数字 一.摩尔投票法 一.摩尔投票法 核心理 ...

最新文章

  1. 计算机调查取证分析篇
  2. 【控制】《复杂运动体系统的分布式协同控制与优化》-方浩老师-第2章-基于速度估计的多欧拉-拉格朗日系统分布式控制
  3. YOLOv5-LibTorch
  4. 欢迎使用CSDN-markdown编辑器!!!
  5. php页面添加链接,怎么给一个PHP密码访问页面加超链接
  6. php 自己封装一个调用第三方接口的函数
  7. kafka处理大数据包
  8. java如何看jdk文档_如何在IntelliJ IDEA中查看JDK外部文档?
  9. 电商管理系统的作用?好用的电商管理系统有哪些特点?
  10. 青山常在,绿水长流,又一个新地方了
  11. ios 检查设备距离与电池状态及判断是否是Retina显示屏
  12. 怎样检测php语法错误,检查php的语法错误
  13. 【NLP】神经网络语言模型(NNLM)
  14. 快速搭建去中心化视频分享平台peertube
  15. 浏览器播放rtsp视频,基于nodeJs
  16. IntelliJ IDEA破解版 2017.3.4 Ultimate下载安装和JetbrainsCrack-2.7.jar激活教程
  17. VSCode 代码块/全文 折叠/展开 快捷键
  18. 海尔“1000天流程再造”
  19. leetCode第199场周赛学习
  20. 数组中常用的高阶方法

热门文章

  1. 配置信息的优化,类型转换器
  2. 程序架构--BS,CS
  3. php获取外部URL,使用PHP从外部API / URL获取信息
  4. 正则不能输入特殊字符_正则表达式语法学习和在线练习
  5. backlog配置_TCP/IP协议中backlog参数
  6. linux 中如何查看块设备,在linux中,如何确定使用块设备的进程?
  7. xml转svg_C# Excel 转PDF/图片/HTML/TXT/XML/XPS/CSV/ODS/SVG/EMF
  8. h5 bootstrap 小程序模板_软件测试人员必知H5/小程序测试点
  9. pytorch数据预处理
  10. 全能终端神器 --- MobaXterm 、开启 linux 远程桌面