赞
踩
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]
.
这道题如果使用O(N^2)的穷搜方法是绝对超时的。·但是从最右边元素开始处理的想法却是正确的。
使用什么方法的可以减少查询次数呢?最妙的做法是我在LeetCode 的solution里看到的,这个方法在处理每个元素的同时维护了一棵二叉查找树,这样我们每次处理一个新的元素时,只需要从根节点处对其进行插入,并且记录每次走右子树时的sum值(因为右子树值均大于左子树),而每个右子树节点都记录了其左子树的节点数(包括重复的值)。
因此,先定义节点类
- class Node {
- public Node(int dup,int val){
- this.dup = dup; //记录重复次数
- this.val = val;
- this.left = null;
- this.right = null;
- }
- public void incDup(){
- this.dup++;
- }
- public int getDup(){
- return this.dup;
- }
- private int dup;
- public int sum; //记录该节点左子树中节点总数
- public int val;
- public Node left;
- public Node right;
- }

- public Node insert(List<Integer> counts,Node node,int curvalue,int sum){
- if (node == null) {
- node = new Node(1,curvalue);
- counts.add(0,sum);
- }
- else if (node.val == curvalue) {
-
- node.incDup();
- counts.add(0,sum+node.sum);
- }
- else if (node.val > curvalue) {
- node.sum++;
- node.left = insert(counts,node.left,curvalue,sum);
- }
- else node.right = insert(counts,node.right,curvalue,sum+node.getDup()+node.sum);
- return node;
- }

完整的solution:
- class Node {
- public Node(int dup,int val){
- this.dup = dup;
- this.val = val;
- this.left = null;
- this.right = null;
- }
- public void incDup(){
- this.dup++;
- }
- public int getDup(){
- return this.dup;
- }
- private int dup;
- public int sum;
- public int val;
- public Node left;
- public Node right;
- }
- public class Solution {
- public List<Integer> countSmaller(int[] nums) {
- List<Integer> counts = new ArrayList<Integer>();
- Node root = null;
- for (int i = nums.length-1;i>=0;i--){
- root = insert(counts,root,nums[i],0);
- }
- return counts;
- }
- public Node insert(List<Integer> counts,Node node,int curvalue,int sum){
- if (node == null) {
- node = new Node(1,curvalue);
- counts.add(0,sum);
- }
- else if (node.val == curvalue) {
-
- node.incDup();
- counts.add(0,sum+node.sum);
- }
- else if (node.val > curvalue) {
- node.sum++;
- node.left = insert(counts,node.left,curvalue,sum);
- }
- else node.right = insert(counts,node.right,curvalue,sum+node.getDup()+node.sum);
- return node;
- }
-
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。