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 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的更多相关文章
- [LeetCode] 315. Count of Smaller Numbers After Self (Hard)
315. Count of Smaller Numbers After Self class Solution { public: vector<int> countSmaller(vec ...
- leetcode 315. Count of Smaller Numbers After Self 两种思路(欢迎探讨更优解法)
说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...
- leetcode 315. Count of Smaller Numbers After Self 两种思路
说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...
- [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 ...
- LeetCode 315. Count of Smaller Numbers After Self
原题链接在这里:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: You are given an inte ...
- 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 ...
- 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 ...
- 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 ...
- 第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树
Leetcode315 题意很简单,给定一个序列,求每一个数的右边有多少小于它的数. O(n^2)的算法是显而易见的. 用普通的线段树可以优化到O(nlogn) 我们可以直接套用主席树的模板. 主席树 ...
随机推荐
- Unable to find messages file 'cscui.dll' 问题解决
之前在工作机器上安装VS 2015卡死,结束进程,安装失败一直无法使用,昨天下班开着电脑把VS 2015卸载了,今天早上来,以前正确的项目现在生成都报错 "Unable to find me ...
- 用openvswitch配置跨节点的docker网络环境
在一篇随笔中,我们已经尝试了在不依赖工具的情况下设置docker的ip,连我都想吐槽,MD单机都这么麻烦,在多机的环境中岂不是要了我的小命! 本文就是为了多机环境中各个节点的容器通信而做的,网络拓朴如 ...
- (转)WCF开发框架形成之旅---WCF的几种寄宿方式
WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便.高效提供服务调用.本文分别对这几种方式进行详 ...
- Axure 使用心得总结
Axure的本意是高效快捷的完成原型制作,能够清晰的说明功能,交互就是好的,"够漂亮"就行,不需要做到很完美,至于完美还是交给专业的UI吧. 一些心得记录下来: 1.下载一些常用的 ...
- IIS发布问题汇总
1.未能加载文件或程序集“System.Data.SQLite” 在IIS界面选择应用程序池->选择所使用的.net 版本->高级设置->将"使用32位应用程序" ...
- ZYNQ学习之二-EMIO
---恢复内容开始--- 本次试验学习和掌握zynq的emio的使用,是通过PS控制PL端的GPIO. 1.创建硬件工程,主要就是添加EMIO就可以.当然了创建工程的时候还要注意DDR的设置,根据自己 ...
- Linux 任务计划
一.配置cron实现自动化 使用cron实现任务自动化可以通过修改/etc/crontab文件以及使用crontab命令实现,其结果是一样的. 1./etc/crontab文件实现自动化 cron守护 ...
- NOIP模拟赛-护花
[题目描述] 约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽 ...
- Scorpio-CSharp总链接
简介 源码目录介绍
- oracle-关于dual
来源:百度知道1. dual 是一张表.是一张只有一个字段,一行记录的表. 2.习惯上,我们称之为'伪表'.因为他不存储主题数据.3. 他的存在,是为了操作上的方便.因为select 都是要有特定对象 ...