zoukankan      html  css  js  c++  java
  • 算法复习之 树状数组 + 数组离散化求解逆序对

    1. 问题:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
    class Solution {
    
        int lowBit(int x) {
            return x & (-x);
        }
    
        int sum(int[] c, int x) {
            int ret = 0;
            while(x > 0) {
                ret += c[x];
                x -= lowBit(x);
            }
            return ret;
        }
    
        public void add(int[] c, int n, int x, int d) {
            while(x <= n) {
                c[x] += d;
                x += lowBit(x);
            }
        }
    
        public int reversePairs(int[] nums) {
            /*
                使用树状数组可以求解逆序对问题。对于数组中的某个数字i,对他的处理方式是,首先将树状数组中下表i的值 + 1,表示树状数组中目前存储的i元素多了一个。然后统计比他小的数字在他后面的个数(也即查询目前树状数组中前(i - 1)项的和。
                上述我们使用树状数组中的下标对应了数组中的数值i。由于不知道数组的最大值和最小值,我们选用离散化将数字离散到(1 ~ m)上,其中m的值为数组中不重复元素的个数。
            */
            Set <Integer> set = new TreeSet<>();
            for(int i = 0; i < nums.length; i ++) {
                set.add(nums[i]);
            } // 将数组中的值排序并且去重
            int idx = 1;
            Map<Integer, Integer> mp = new HashMap<>();
            for(Integer v : set) {
                mp.put(v, idx ++);
            } // 使用map结构实现离散化,将值v离散化为idx
            int ans = 0;
            int[] c = new int[idx];
            for(int i = nums.length - 1; i >= 0 ; i --) {
                int temp = mp.get(nums[i]); // 对于每个数字,获取到他在离散化后数组中的值
                add(c, idx - 1, temp, 1); // 对这个较小的,但是在数组中大小顺序不变的数字进行树状数组的操作
                ans += sum(c, temp - 1);
            }
            return ans;
        }
    }
    
    时间并不会因为你的迷茫和迟疑而停留,就在你看这篇文章的同时,不知道有多少人在冥思苦想,在为算法废寝忘食,不知道有多少人在狂热地拍着代码,不知道又有多少提交一遍又一遍地刷新着OJ的status页面…… 没有谁生来就是神牛,而千里之行,始于足下!
  • 相关阅读:
    浅谈关于JavaScript解析XML文件的注意事项
    个人总结的Struts2拦截器使用和拦截栈的配置,基于注解的方式
    使用Awstats统计部署在tomcat中的网站数据
    spring4.x + hibernate4.x 配置详解
    Java内部类总结
    Java中static的使用
    Java多线程基础知识总结
    Java线程经典面试题
    C#/.net七牛云存储上传图片(文件)操作
    Special Solver Parameters
  • 原文地址:https://www.cnblogs.com/bianjunting/p/14690137.html
Copyright © 2011-2022 走看看