You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

Example:

Given nums = [5, 2, 6, 1]

To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.

Return the array [2, 1, 1, 0].

public class Solution {
public List<Integer> countSmaller(int[] nums) {
// 求得nums在按序排列的数组中的脚标位置
int[] temp = nums.clone();
Arrays.sort(temp);
for (int i = 0; i < temp.length; i++) {
nums[i] = Arrays.binarySearch(temp, nums[i]);
}
// 这里用Integer是为了使用Arrays.asList
Integer[] ans = new Integer[temp.length];
int[] bit = new int[temp.length];
// 遍历的时候使用逆序是因为位于数组最后面的数,逆序程度是最低的
for (int i = temp.length-1; i >= 0; i--) {
/**
* 用bit数组的前num[i]项和作为逆序程度
*
* 最后一位的逆序永远是0
* 次高位的逆序要么是1要么是0,最大值只能是1
* query方法正好保证了这点。
* 它查询bit数组中前nums[i]项的和
* 如果最高位比次高位要小,那么计算次高位项的和就会加1,相反就不回家
*/
ans[i] = query(bit,nums[i]);
/**
* 修改那条链上的数据+1
*/
add(bit,nums[i]+1,1);
} return Arrays.asList(ans);
} /**
* 功能:
* 修改bit数组脚标i对应的链上的数据
* (因为求前n项和,是根据那几个数来求的,所以改动一个数要同时改动那几个数)
* @param bit 树状数组
* @param i 数组脚标
* @param val 脚标所对应的树枝要修改的值
*/
private void add(int[] bit, int i, int val) {
for (;i<bit.length;i+=lowbit(i)) {
bit[i]+=val;
}
} /**
* 查询bit数组中前i项的和
* @param bit 树状数组
* @param i 数组脚标
* @return
*/
private Integer query(int[] bit, int i) {
int ans = 0;
for (;i>0;i-=lowbit(i)) {
ans += bit[i];
}
return ans;
}
/**
* 求二进制的i中第一个1对应的十进制值
* @param i
* @return i转化为二进制之后第一个1所对应的值
*/
private int lowbit(int i) {
return i&(-i);
}
}

简单的解释一下ans数组的产生:

只要后面一位比前面一位要小,那么前面一位求前n项和的时候就会多加一个1.所以加了多少个1,逆序数就有几个。

前n项和的值中每一个1代表了一个逆序数。

分别对:896859    896853的分析

树状数组图

315. Count of Smaller Numbers After Self的更多相关文章

  1. [LeetCode] 315. Count of Smaller Numbers After Self (Hard)

    315. Count of Smaller Numbers After Self class Solution { public: vector<int> countSmaller(vec ...

  2. leetcode 315. Count of Smaller Numbers After Self 两种思路(欢迎探讨更优解法)

    说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...

  3. leetcode 315. Count of Smaller Numbers After Self 两种思路

    说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...

  4. [LeetCode] 315. Count of Smaller Numbers After Self 计算后面较小数字的个数

    You are given an integer array nums and you have to return a new counts array. The countsarray has t ...

  5. LeetCode 315. Count of Smaller Numbers After Self

    原题链接在这里:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: You are given an inte ...

  6. 315.Count of Smaller Numbers After Self My Submissions Question

    You are given an integer array nums and you have to return a new counts array. Thecounts array has t ...

  7. 315. Count of Smaller Numbers After Self(Fenwick Tree)

    You are given an integer array nums and you have to return a new counts array. The counts array has ...

  8. 315. Count of Smaller Numbers After Self(二分或者算法导论中的归并求逆序数对)

    You are given an integer array nums and you have to return a new counts array. The counts array has ...

  9. 第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树

    Leetcode315 题意很简单,给定一个序列,求每一个数的右边有多少小于它的数. O(n^2)的算法是显而易见的. 用普通的线段树可以优化到O(nlogn) 我们可以直接套用主席树的模板. 主席树 ...

随机推荐

  1. 黄聪:如何为IIS增加svg和woff等字体格式的MIME

    现在字体图标已经渐渐代替了图片了,移动端用起来也很方便. 使用了字体文件来显示矢量的图标,为了能在IIS上正常显示图标,可以通过增加iis的MIME-TYPE来支持图标字体文件 下面就把IIS增加sv ...

  2. mfc release 版本 内存不足 的解决方法

  3. json&pickle&xml

    json .dumps()    变成 json 的字符串 import json dic={"name":"alex"} data=json.dumps(di ...

  4. MVC4中 访问webservice 出现无法找到资源的错误

    出现这个情况,是mvc将webservice.asmx解析成了控制器,下面先将这个控制器忽略 继续访问出现这样的错误: 下面修改配置文件 访问成功

  5. java 事件监听 - 控件

    java 事件监听 //事件监听 //事件监听,写了一个小案例,点击按钮改变面板的颜色. import java.awt.*; import javax.swing.*; import java.aw ...

  6. SQL加权限

    grant view definition on 存储过程名字 to 用户名

  7. 【Linux编程】关于tcp_time_stamp

    今天看了一下cubic中使用到的tcp_time_stamp变量,往上查到的描述如下: 定义: include/net/tcp.h, line 707 #define tcp_time_stamp ( ...

  8. 第二周:Java For循环方法简介

    1.for循环的作用 Java当中循环的意思就是让Java程序重复地执行某些语句.在程序设计时,常常需要处理大量的重复动作, 采用循环结构可以降低程序书写的长度和复杂度可使复杂问题简单化,提高程序的可 ...

  9. Python-6 分支 循环

    #1 循环 while 条件: 循环体 for 目标 in 表达式: 循环体   表达式可为:range(start,stop,step) break--终止当前循环,并跳出当前循环体. contin ...

  10. 剑指Offer:解决难题时的三大方法

    1.画图 让抽象的东西变得直观生动起来.比如设计二叉树,链表,栈,队列这些数据结构时. 2.举例子 同样可以化抽象为直观.能够更清晰的展现思路.从例子归纳出一般做法. 3.分解 有时问题本身是比较复杂 ...