当前位置: 首页 > news >正文

数组中的逆序对

题目描述
有一组数,对于其中任意两个数组,若前面一个大于后面一个数字,则这两个数字组成一个逆序对。请设计一个高效的算法,计算给定数组中的逆序对个数。

给定一个int数组A和它的大小n,请返回A中的逆序对个数。保证n小于等于5000。

测试样例:
[1,2,3,4,5,6,7,0],8
返回:7
  1. 对于每一个index为i的元素,需要统计index为0~i-1的元素中值大于它的个数,通过构建二叉树维护0~i-1的数据
import java.util.*;

public class AntiOrder {
    
    Node root;
    
    public int count(int[] A, int n) {
        // write code here
        if(n==0)
            return 0;
        root = new Node(A[0]);
        int res = 0;
        for(int i=1; i<n; i++){
            root.insert(A[i]);
            res += root.getRank(A[i]);
        }
        return res;
    }
}

class Node{
    int val;
    Node left;
    Node right;
    
    Node(int v){
        val = v;
    }
    int leftSize = 0;
    
    public void insert(int v){
        if(v>val){
            if(left!=null)
                left.insert(v);
            else{
                left = new Node(v);
            }
            leftSize += 1;
        }else{
            if(right!=null)
                right.insert(v);
            else
                right = new Node(v);
        }
    }
    
    public int getRank(int v){
        if(v==val)
            return leftSize;
        else if(v>val){
            return left.getRank(v);
        }
        else{
            return leftSize + 1 + right.getRank(v);
        }
    }
}
  1. 二分法

统计每一个小段内部的逆序对,在合并时统计段之间的逆序对数

import java.util.*;

public class AntiOrder {
    public int count(int[] A, int n) {
        // write code here
        return c(A, 0, n-1);
    }
    
    public int c(int[] A, int left, int right){
        if(left>=right)
            return 0;
        int mid = left + (right-left)/2;
        int count1 = c(A, left, mid);
        int count2 = c(A, mid+1, right);
        return count1 + count2 + merge(A, left, mid, right);
    }
    
    public int merge(int [] A, int left, int mid, int right){
        int [] temp = new int[right-left+1+1];
        int k = 0;
        int i=left, j=mid+1;
        int result = 0;
        while(i<=mid&&j<=right){
            if(A[i]<A[j])
                temp[k++] = A[i++];
            else{
                result += mid-i+1;
                temp[k++] = A[j++];
            }
        }
        while(i<=mid)
            temp[k++] = A[i++];
        while(j<=right)
            temp[k++] = A[j++];
        for(int p=left; p<=right; p++)
            A[p] = temp[p-left];
        return result;
    }
}

相关文章:

  • Windows 8 应用商店应用开发 之 氛围光传感器
  • 子串判断
  • arm汇编程序中的[|]
  • 实时中位数
  • 【spring】IllegalArgumentException Can not set field to $Proxy 在spring中使用事物或AOP遇到的错误...
  • 约瑟夫问题
  • C#实现UDP分包组包
  • tomcat 集群搭建
  • 善变的同伴
  • IDC:PC 今年第一季度出货量继续下滑趋势,比起去年同期跌了13.9%
  • 非递归中序,后序遍历二叉树
  • Eclipse安装aptana
  • udp datetime服务
  • linux信号浅谈
  • hdu 2142 Can you find it?
  • CSS 三角实现
  • Facebook AccountKit 接入的坑点
  • IDEA 插件开发入门教程
  • Java知识点总结(JavaIO-打印流)
  • k8s 面向应用开发者的基础命令
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • Yii源码解读-服务定位器(Service Locator)
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 对象管理器(defineProperty)学习笔记
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 以太坊客户端Geth命令参数详解
  • 异步
  • 鱼骨图 - 如何绘制?
  • 7行Python代码的人脸识别
  • C# - 为值类型重定义相等性
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (转)大型网站的系统架构
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .net 中viewstate的原理和使用
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • .net连接oracle数据库
  • .Net转前端开发-启航篇,如何定制博客园主题
  • /usr/lib/mysql/plugin权限_给数据库增加密码策略遇到的权限问题
  • ??javascript里的变量问题
  • [AutoSAR系列] 1.3 AutoSar 架构
  • [BZOJ 1040] 骑士
  • [BZOJ 3282] Tree 【LCT】
  • [BZOJ1040][P2607][ZJOI2008]骑士[树形DP+基环树]
  • [CentOs7]图形界面
  • [ComfyUI进阶教程] animatediff视频提示词书写要点
  • [Design Pattern] 工厂方法模式
  • [IE9] IE9 RC版下载链接
  • [IE技巧] 使IE8以单进程的模式运行
  • [JavaEE] 线程与进程的区别详解