Hard-题目11:315. Count of Smaller Numbers After Self
来源:互联网 发布:手机养狗软件 编辑:程序博客网 时间:2024/05/17 19:19
题目原文:
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].
题目大意:
给出一个数组,计算每个元素右边有几个比它小的元素,组成一个新的数组返回。
题目分析:
这里需要用到一种高级数据结构叫做“树状数组”,又叫Binary Indexed Tree或Fenwick tree,其特点是查询和修改节点都是O(logn)的,用于快速求数组的前n项和。
构建方法:
设原数组是a[1…n],按如图方式构造数组c:(from 百度百科)
C[1]=a[1],c[2]=a[1]+a[2],….c[8]=a[1]+…+a[8],
树状数组有两个api,这两个api的时间复杂度都是O(logn)的,n为数组长度,具体实现略,有兴趣可以自行百度。
void add(int* tree,int k,int num) // 在a[k]上增加num,更新树状数组treeint get(int* tree,int k) // 求a[1]+…+a[k]的和
再回到这道题,先求最小值和最大值,记为min和max,然后平移区间使得min=1,(若min不为1,则整个数组都减去min和1的差值)然后基于数组num(其中最小值修正为1,对应最大值为max-min+1) 构建树状数组tree[1…max-min+1],其中对应的a数组的a[i]代表num数组中i出现的次数。
接下来逆向扫描num数组,每扫到一个元素num[i],调用get函数求树状数组中a[1]到a[num[i]-1]的和,这个和值就是num数组中i右边比num[i]小的个数!!(这里最难理解,稍后说明),再调用add函数把num[i]加到a中。
时间复杂度:扫描一遍数组O(n),每个元素调用了两个O(logk)复杂度的api,其中k为树状数组长度,总复杂度为O(nlog(max-min)).
上面说了这么多有点抽象,下面举个栗子~~(看明白的童鞋或者嫌我墨迹的童鞋略过吧)
输入数组:[5,6,-1,1] (答案为:[2,2,0,0])
首先修正数组使得最小值为1(否则会出现数组越界):
nums[]=[6,8,1,3],min=1,max=8
然后构建tree[1..8](因为tree的值很难写,就写图中下方的a数组)
逆向扫描数组:此时a数组初始化为全0
nums[i]=3,调用get函数求a[1]+a[2]为0(即1,2这两个数还没出现过),调用add函数使得a[3]++,
此时a数组:[0,0,1,0,0,0,0,0]
Nums[i]=1,调用get函数返回0(因为1左边没有数据了),调用add函数使得a[1]++.
此时a数组:[1,0,1,0,0,0,0,0]
Nums[i]=8,调用get函数求a[1]+…+a[7]=2,调用add函数使得a[8]++
此时a数组:[1,0,1,0,0,0,0,1]
Nums[i]=6,调用get函数求a[1]+…+a[5]=2,调用add函数使得a[6]++.
此时a数组:[1,0,1,0,0,1,0,1]
从下往上读取get的返回值,得到数组[2,2,0,0]即为答案。
源码:(language:java)
public class Solution { public List<Integer> countSmaller(int[] nums) { LinkedList<Integer> res = new LinkedList<Integer>(); if (nums == null || nums.length == 0) { return res; } // find min value and minus min by each elements, plus 1 to avoid 0 element int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int i = 0; i < nums.length; i++) { min = (nums[i] < min) ? nums[i]:min; } int[] nums2 = new int[nums.length]; for (int i = 0; i < nums.length; i++) { nums2[i] = nums[i] - min + 1; max = Math.max(nums2[i],max); } int[] tree = new int[max+1]; for (int i = nums2.length-1; i >= 0; i--) { res.addFirst(get(nums2[i]-1,tree)); update(nums2[i],tree); } return res; } private int get(int i, int[] tree) { int num = 0; while (i > 0) { num +=tree[i]; i -= i&(-i); } return num; } private void update(int i, int[] tree) { while (i < tree.length) { tree[i] ++; i += i & (-i); } }}
成绩:
8ms,beats 97.33%,众数11ms,8.79%
Cmershen的碎碎念:
返回类型是List,因为要从下往上读get函数的返回值,故使用链表的实现类LinkedList,因为提供了addFirst()方法.
- Hard-题目11:315. Count of Smaller Numbers After Self
- Leetcode 315. Count of Smaller Numbers After Self[hard]
- 315. Count of Smaller Numbers After Self Hard
- leetcode 315. Count of Smaller Numbers After Self(Hard)
- LeetCode题目:315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self***
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- Hard-题目10:33. Search in Rotated Sorted Array
- 虚拟机,提高测试的效率
- C语言的函数(第二篇章:函数的传值与传址)
- spring整合redis集群遇到的问题及MyEclipse下Maven的安装配置
- 工作笔录(一)
- Hard-题目11:315. Count of Smaller Numbers After Self
- python pdb调试
- Mirantis OpenStack Fuel9.0社区版安装测试
- Introduction to DirectShow Application Programming
- 软件工程(二十五)
- Hard-题目12:115. Distinct Subsequences
- 输入2个整数,计算两数相除的商(q)和余数(r)。
- 学习的进度慢,没技巧!
- Hard-题目13:72. Edit Distance