[剑指offer][JAVA]面试题[51][数组中的逆序对][归并排序]

【问题描述】面试题51.数组中的逆序对 (困难)

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

【解答思路】

1. 暴力 超时
  • 枚举所有数组
    -符合条件累加
    时间复杂度:O(N^2) 空间复杂度:O(1)
public int reversePairs(int[] nums) {int n = nums.length;int count = 0 ;if(n == 0){return 0;}for(int i = 0 ; i< n-1;i++){for(int j = i+1 ;j < n ;j++){if(nums[i]>nums[j]){count++;}}    }return count;}
2. 归并排序

  • 合并1 前面有四个树比1大 总数+4

#####计数关键
count = mid - i -1

时间复杂度:O(NlogN) 空间复杂度:O(N)

 public int reversePairs(int[] nums) {int  len = nums.length;if(len <2 ){return  0;}int[] copy = new int[len];for (int i = 0; i < len ; i++) {copy[i] = nums[i];}int[] temp = new int[len];
//引入temp[] 为了避免每次合并时需要创建、销毁新的数组,避免下标问题return  reversePairs(copy,  0 ,len - 1, temp);}/**** @param nums* @param left* @param right* @param temp* @return*/private int reversePairs(int[] nums, int left, int right, int[] temp) {if(left == right){return 0;}//防止溢出int mid = left + (right- left) /2;int leftPairs = reversePairs(nums, left, mid , temp);int rightPairs = reversePairs(nums, mid+1, right, temp);//优化归并排序if(nums[mid] <= nums[mid+1]){return   leftPairs + rightPairs;}int crossPairs = mergeAndCount(nums, left, mid ,right, temp);return  leftPairs + rightPairs + crossPairs;}/**** @param nums* @param left* @param mid* @param right* @param temp* @return*/private int mergeAndCount(int[] nums, int left, int mid, int right, int[] temp) {//区间复制到temp[]数组for (int i = left; i <=right ; i++) {temp[i] =  nums[i];}int i = left ;int j = mid+1;int count = 0 ;for (int k = left; k <= right ; k++) {//前半部分遍历完if(i == mid+1){nums[k] = temp[j];j++;}//后半部分遍历完else if(j == right+1){nums[k] = temp[i];i++;}//count计数 逻辑(else if -else )   <= 稳定性 else if(temp[i]<=temp[j]){nums[k] = temp[i];i++;}else {nums[k] = temp[j];j++;count += (mid-i+1);}}return  count;}

【总结】

1. 归并排序思想

2. 归并排序优化
  if(nums[mid] <= nums[mid+1]){return   leftPairs + rightPairs;}
3. 规避排序模板
import java.util.Arrays;public class MergeSort2 {// 用于合并两个有序数组的辅助数组,使用它是为了避免每次归并都重复开辟空间// 它的长度,就是数组的长度,每次只用它的一部分,直到最后一次归并,使用它的全部private int[] temp;// 自顶向下的归并排序实现 2public void sort(int[] arr) {int len = arr.length;temp = new int[len];mergeSort(arr, 0, len - 1);}private void mergeSort(int[] arr, int left, int right) {// 修复1:为了防止计算 int mid = (left + right) / 2; 整形溢出,应该像下面这样计算 midint mid = left + (right - left) / 2;mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);// 优化2:如果 arr 数组已经前后有序(前面数组中的最后一个元素不大于后面数组中的第 1 个元素)if (arr[mid] <= arr[mid + 1]) {return;}mergeOfTwoSortArray(arr, left, mid, right);}private void mergeOfTwoSortArray(int[] arr, int left, int mid, int right) {// 优化3:使用一个全局的辅助数组,避免每次都开辟新的内存空间去优化,这样做反而编程实现更简单,不用考虑索引的偏移for (int i = left; i <= right; i++) { // 闭区间,所以 right 这个索引也要赋值temp[i] = arr[i];}// temp 的 [left,mid] 有序// temp 的 [mid+1,right] 有序,现在要将它们整理成有序,放回 arr 中,一个一个放就好了int i = left;int j = mid + 1;for (int k = left; k <= right; k++) {// i 用完if (i > mid) {arr[k] = temp[j];j++;} else if (j > right) {  // j 用完arr[k] = temp[i];i++;} else if (temp[i] < temp[j]) {arr[k] = temp[i];i++;} else {arr[k] = temp[j];j++;}}}public static void main(String[] args) {int[] nums = {8, 4, 3, 6, 5, 1};MergeSort2 mergeSort2 = new MergeSort2();mergeSort2.sort(nums);System.out.println(Arrays.toString(nums));}
}

参考网站:https://liweiwei1419.gitee.io/leetcode-algo/leetcode-by-tag/sorting-algorithm/merge-sorting.html#%E4%BC%98%E5%8C%96%E7%9A%84%E5%AE%9E%E7%8E%B0

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019年1月16日【第三天学习】

2019年1月16日星期三 任务一、运行CrackMe1.exe&#xff0c;提示 "嗯&#xff0c;对了" 代表成功。首先修改exe使得出现成功提示&#xff0c;其次不修改exe输入正确的密码达到成功的目的。 hint:https://blog.csdn.net/Nagi_Way/article/details/68961121 使用.Net的…

玩转oracle 11g(46):图解oracle数据库

1构成 由实例和数据库构成 2构成 3市例 4构成

[Leedcode][JAVA][第46题][全排列][回溯算法]

【问题描述】 46.全排列 &#xff08;中等&#xff09; 给定一个 没有重复 数字的序列&#xff0c;返回其所有可能的全排列。示例:输入: [1,2,3] 输出: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1] ]【解答思路】 1. 回溯 时间复杂度&#xff1a;O(NN&#xff01;) 空间…

java学习(167):生产者消费者问题

class Ck {private char[] r1 new char[8];private int wp 0;public synchronized void shengchan(char aa) {while (wp r1.length) //满了try {this.wait();} catch (Exception e) {}this.notify();//叫醒另一个线程&#xff0c;当前线程处于就绪状态r1[wp] aa;wp;System.…

[Markdown语法][快速入门][CSDN]

Markdown语法Markdown学习资料【使用建议】快捷键目录标题文本样式列表链接代码片表格注释 & 注脚自定义列表LateX数字公式插入甘耐图插入UML图插入Mermaid流程图插入Flowchart流程图Markdown学习资料 「中文文案排版指北」 「官方文档」 [科学上网] 【使用建议】 Mark…

常用开发环境搭建配置教程(OneStall)

最近想要做一个小东西&#xff0c;用到了下面几个中间件或者环境&#xff1a; Java Tomcat Maven MongoDB ZooKeeper Node 并且恰好碰到腾讯云打折&#xff0c;云主机原价100多一个月&#xff0c;花了30块钱买了三个月。买下后立即动手准备开始环境配置。 说到环境&#xff0c;…

sqlserver:(1):sqlserver安装超详细

1第一步&#xff0c;下载对应的镜像文件链接&#xff1a; https://pan.baidu.com/s/1nBwjrukxCAMD4xLdYofPXA 提取码&#xff1a;9rv7 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 然后&#xff0c;点击左面安装&#xff0c;在显示页面中点击全新SQLServer独…

linux 5识别网卡,CentOS 5.5系统识别不了Atheros AR8151网卡怎么办?

在安装完CentOS 5.5系统后&#xff0c;有些人出现无法上网的现象&#xff0c;经检测发现是Atheros AR8151网卡识别不了&#xff0c;遇到这种问题不用怕&#xff0c;下面小编就给大家介绍下CentOS 5.5无法识别Atheros AR8151网卡的解决方法。现象前段时间&#xff0c;在一台电脑…

混合代码块 Markdown Leedcde

混合代码块 Markdown&#xff08;仅限Leedcode&#xff09; 使用说明 Markdown 语法 注意语言后有空格 &#xff01; 展示效果

java学习(168):java连接SQL server数据库

1安装sql server数据库 2打开eclipse写入以下代码 package sjk;import java.sql.*;public class Main {//这里可以设置数据库名称private final static String URL "jdbc:sqlserver://localhost:1433;DatabaseNametest";private static final String USER"sa&…

mongo:(1)nosql简介

MongoDB 是一个基于分布式文件存储的数据库。由 C 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。 MongoDB 是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。 NoSQL 简介 NoSQL(NoSQ…

[Leedcode][JAVA][第33题][搜索旋转排序数组]

【问题描述】[33. 搜索旋转排序数组] [中等] 假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如&#xff0c;数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。搜索一个给定的目标值&#xff0c;如果数组中存在这个目标值&#xff0c;则返回它的索引&#xff0…

001. Ansible简介

一 简介 Ansible是一款极其简单的自动化运维工具, 基于Python开发, 集合了众多运维工具(puppet, cfengine, chef, func, fabric)的优点。 实现了批量系统配置, 批量程序部署, 批量运行命令等功能。 Ansible是基于模块工作的, 本身没有批量部署的能力。真正具有批量部署的是ansi…

mongo:(2)mongoDB简介

什么是MongoDB ? MongoDB 是由C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB 将数据存储为一个…

linux分割图片软件,桌面应用|5 种拆分 Linux 终端的方法

本文介绍了 Linux 提供的拆分终端的方法&#xff0c;它能够帮助你完成多任务工作。那么&#xff0c;你最喜欢哪一款终端复用工具呢&#xff1f;没有什么问题是不能用一个 Linux 终端解决的&#xff0c;如果不行&#xff0c;那就用两个。很早以前&#xff0c;终端其实是一个物理…

[剑指offer][JAVA][面试题56 - I][第260题][位运算][HashSet]

【问题描述】 [面试题56 - I] [数组中数字出现的次数] 一个整型数组 nums 里除两个数字之外&#xff0c;其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n)&#xff0c;空间复杂度是O(1)。示例 1&#xff1a;输入&#xff1a;nums [4,1,4,6] …

mongo:(3)windows上mongoDB安装

1打开程序 2下一步 3下一步 4custom自定义 5取消勾选&#xff0c;安装 6安装完成以后 在bin目录下建文件夹 7创建结束&#xff0c;将mongo.conf放在根目录下 8管理员运行 Cd D:\Program Files\MongoDB\Server\3.6\bin 然后 9 >mongod --config D:\mongo\mongo.conf --i…

LOJ10121 与众不同

题目描述 A 是某公司的 CEO&#xff0c;每个月都会有员工把公司的盈利数据送给 A&#xff0c;A 是个与众不同的怪人&#xff0c;A 不注重盈利还是亏本&#xff0c;而是喜欢研究「完美序列」&#xff1a;一段连续的序列满足序列中的数互不相同。 A 想知道区间 [L,R] 之间最长的完…

[计算机网络][总结][常见问题][TCP][三次握手][四次挥手]

TCP三次握手 四次挥手 三次握手 目的&#xff1a;保证传输的可靠性,为了防止已失效的连接请求报文段突然又传送到了服务端&#xff0c;因而产生错误。主要防止资源的浪费。 具体过程&#xff1a;当客户端发出第一个连接请求报文段时并没有丢失&#xff0c;而是在某个网络节点…

第二十二期:淘宝技术架构分享

一&#xff0c;淘宝技术架构 1.UIC: 用户中心(User Interface Center),提供所有用户信息相关的读写服务&#xff0c;如基本信息&#xff0c;扩展信息&#xff0c;社区信息&#xff0c;买卖家信用等级等等。 淘宝现在有两类卖家B 和C&#xff0c;这是通过在用户身上打不同的标签…