2021-03-08:在一个数组中,任何一个前面的数a,和任何一个后面的数b,如果(a,b)是降序的,就称为逆序对。返回逆序对个数。
2021-03-08:在一个数组中,任何一个前面的数a,和任何一个后面的数b,如果(a,b)是降序的,就称为逆序对。返回逆序对个数。
福哥答案2021-03-08:
1.归并排序,从右往左,相等拷右。有代码。
2.归并排序模板。有代码。
代码用golang编写,代码如下:
package main
import "fmt"
func main() {
    if true {
        arr := []int{3, 1, 7, 0, 2}
        ret := reverPairNumber1(arr)
        fmt.Println("1.从右往左,相等拷右:", ret)
    }
    if true {
        arr := []int{3, 1, 7, 0, 2}
        ret := reverPairNumber2(arr)
        fmt.Println("2.归并排序模板:", ret)
    }
}
func reverPairNumber1(arr []int) int {
    arrLen := len(arr)
    if arrLen <= 1 {
        return 0
    }
    return process1(arr, 0, arrLen-1)
}
func process1(arr []int, L int, R int) int {
    curLen := R - L + 1
    if curLen <= 1 {
        return 0
    }
    //求中点
    M := L + (R-L)>>1
    return process1(arr, L, M) + process1(arr, M+1, R) + merge1(arr, L, M, R)
}
func merge1(arr []int, L int, M int, R int) int {
    //辅助数组
    help := make([]int, R-L+1)
    i := R - L + 1 - 1
    p1 := M
    p2 := R
    res := 0
    //谁小拷谁,相等拷右
    for p1 >= L && p2 >= M+1 {
        if arr[p1] > arr[p2] {
            res += p2 - M
            help[i] = arr[p1]
            p1--
        } else {
            help[i] = arr[p2]
            p2--
        }
        i--
    }
    for p1 >= L {
        help[i] = arr[p1]
        p1--
        i--
    }
    for p2 >= M+1 {
        help[i] = arr[p2]
        p2--
        i--
    }
    //辅助数组拷贝到原数组
    copy(arr[L:R+1], help)
    return res
}
func reverPairNumber2(arr []int) int {
    arrLen := len(arr)
    if arrLen <= 1 {
        return 0
    }
    return process2(arr, 0, arrLen-1)
}
func process2(arr []int, L int, R int) int {
    curLen := R - L + 1
    if curLen <= 1 {
        return 0
    }
    //求中点
    M := L + (R-L)>>1
    return process2(arr, L, M) + process2(arr, M+1, R) + merge2(arr, L, M, R)
}
func merge2(arr []int, L int, M int, R int) int {
    //新增的代码
    ans := 0
    windowR := M + 1
    for i := L; i <= M; i++ {
        for windowR <= R && arr[i] > arr[windowR] {
            windowR++
        }
        ans += windowR - M - 1
    }
    //辅助数组
    help := make([]int, R-L+1)
    i := 0
    p1 := L
    p2 := M + 1
    //谁小拷贝谁
    for p1 <= M && p2 <= R {
        if arr[p1] <= arr[p2] {
            help[i] = arr[p1]
            p1++
        } else {
            help[i] = arr[p2]
            p2++
        }
        i++
    }
    for p1 <= M {
        help[i] = arr[p1]
        p1++
        i++
    }
    for p2 <= R {
        help[i] = arr[p2]
        p2++
        i++
    }
    //辅助数组拷贝到原数组
    copy(arr[L:R+1], help)
    return ans
}
执行结果如下:

左神java代码
剑指 Offer 51. 数组中的逆序对
评论
2021-03-08:在一个数组中,任何一个前面的数a,和任何一个后面的数b,如果(a,b)是降序的,就称为逆序对。返回逆序对个数。的更多相关文章
- 用C#写一个函数,在一个数组中找出随意几个值相加等于一个值   与迭代器对比
		算法!用C#写一个函数,在一个数组中找出随意几个值相加等于一个值比如,数组{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20} 要找出那些数相加等 ... 
- vuex中filter的使用 && 快速判断一个数是否在一个数组中
		vue中filter的使用 computed: mapState({ items: state => state.items.filter(function (value, index, arr ... 
- 在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1)
		题目:在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1) 分析:这道题考察位操作:异或(^),按位与(&),移位操作(>> ... 
- 将String类型的二维数组中的元素用FileOutputStream的write方法生成一个文件
		将String类型的二维数组中的元素用FileOutputStream的write方法生成一个文件import java.io.File;import java.io.FileOutputStre ... 
- 在一个升序数组中添加最少的数字,使得从1--n之间所有的数都能用数组中几个数的和表示
		一个Java的笔试题上面遇到的题,当时没有做出来. 拆分: 序列升序 1--n所有的数都要能表示 用数组中数字的和表示 添加最少的数字 思路:这个要先从小的数开始表示,因为大的数可以用小数表示. 1- ... 
- JS 判断一个字符串是否包含在一个数组中
		var arr = ["白色", "黑色", "红色", "粉色"]; var sel = "黑色" ... 
- JavaScript 中 如何判断一个元素是否在一个数组中
		<script type="text/javascript"> var arrList=['12','qw','q','v','d','t']; console.log ... 
- JS在一个数组中查找某个用户输入的值,返回对应值所在索引值
		方法有很多种 第一:直接循环,判断输出 第二:使用indexOf 正常来说,为了增加工作效率一般会选择indexOf,但是indexOf存在兼容性问题,因此最完善的写法如下 function inde ... 
- 在一个数组中是否存在两个数A、B的和为M
		#include <iostream>#include <algorithm>//#include <vector>using namespace std; int ... 
- NET 在一个数组中查找另一个数组所在起始位置(下标从0开始,未找到返回-1)
		问题: 如果 search 在 dist 中顺序出现而不要求连续出现,那代码应该如何修改?如何计算这种匹配的可能性? 数组 search=[5,4,6],在数据 dist=[1,5,5,4,3,4,5 ... 
随机推荐
- 自定义DOM事件函数封装
			非原生DOM触发,个性化定制的自定义事件. currentTarget(DOM对象):要触发事件的元素节点. type(字符串):触发的事件类型,例如"keydown". bubb ... 
- React16下报错引发整个页面crash的解决方法
			如果报错没有没有被catch,将会引起整个React组件树的unmounting 解决方法:在生命周期中增加componentDidCatch https://reactjs.org/blog/201 ... 
- ESP32 IDF V5.0 编译环境
			方法:环境搭建工具一键安装: 下载链接:https://dl.espressif.com/dl/esp-idf/ 可以选择离线安装方式和在线安装方式,建议:采用离线安装的方式 下载离线安装包之后点击安 ... 
- fastposter v2.13.0 一分钟完成开发海报 [云服务来袭]
			fastposter v2.13.0 一分钟完成开发海报 [云服务来袭] fastposter海报生成器是一款快速开发海报的工具.只需上传一张背景图,在对应的位置放上组件(文字.图片.二维.头像)即可 ... 
- P4555 最长双回文串 解题报告
			看到回文串,于是就想到了马拉车. 马拉车可以帮我们求出每个 \(i\) 的最大扩展距离,容易得出,双回文串就是两个回文串拼一起.当然,两个回文串必须要相交,不然形不成一个字符串. 有的小可爱就会想直接 ... 
- [Elixir/Erlang/Racket] 模式匹配,字符串,哈希表,格式化输出
			https://leetcode.cn/problems/evaluate-the-bracket-pairs-of-a-string/solutions/2057593/s-by-yhm138_-n ... 
- 如何通过Java代码在Word中创建可填充表单
			有时候,我们需要制作一个Word模板文档,然后发给用户填写,但我们希望用户只能在指定位置填写内容,其他内容不允许编辑和修改.这时候我们就可以通过表单控件来轻松实现这一功能.本文将为您介绍如何通过Jav ... 
- Go 语言 new 和 make 关键字的区别
			原文链接: Go 语言 new 和 make 关键字的区别 本篇文章来介绍一道非常常见的面试题,到底有多常见呢?可能很多面试的开场白就是由此开始的.那就是 new 和 make 这两个内置函数的区别. ... 
- jQ的事件
			<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ... 
- 普冉PY32系列(七) SOP8, SOP10和SOP16封装的PY32F003/PY32F002A管脚复用
			目录 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境 普冉PY32系列(三) P ... 
