[剑指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构成

linux一系统是一种,LINUX操作系统是一种( )

LINUX操作系统是一种( )答&#xff1a;多用户多进程系统在选择创业项目之前&#xff0c;应该()。答&#xff1a;以上都是下列选项中不属于面向对象编程语言的是答&#xff1a;C语言解决渠道成员评价、激励不当这一问题的应对策略是( )答&#xff1a;确立合理的评价和激励标准&a…

[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;) 空间…

JCE安装使用报错

"description":"No key was installed for encryption service","status":"NO_KEY" 错误描述{"description": "No key was installed for encryption service","status": "NO_KEY" } 错误原因…

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.…

个人linux版本管理,浅谈各个Linux版本的个人看法

AndroidAndroid手机是一个基于Linux内核的操作系统&#xff0c;这个版本相信大家没有异议&#xff0c;因为与iphone手机可以相提并论以外&#xff0c;就是最好用的操作系统&#xff0c;当然这应该是局限以移动端设备&#xff0c;因为它就是为此而诞生的。优点&#xff1a;可以与…

[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&…

python shelve模块

shelve很简单,操作跟字典操作一样: 1 import shelve 2 f shelve.open(sss) # 有文件会读取,没有会创建..shelve是三个文件,后缀名为.bak.dat.dir(哪个都不要人为去修改) 3 f[name] [1,2,3,{1:2}] # 直接添加键值对,跟字典操作一样,,非常简单 4 print(f[name]) …

linux系统中使用pycharn,在pycharm中使用linux控制台

我是pycharm&#xff0c;virtualenv&#xff0c;linux和git的新手。在pycharm中使用linux控制台我最近开始使用djangoto make webapps的旅程。在我使用崇高来制作脚本之前&#xff0c;现在需要一个更复杂的项目管理系统&#xff0c;例如pycarm。我真的想要一个linux虚拟机并走上…

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;终端其实是一个物理…