题干
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
示例:
输入: [5,2,6,1]
输出: [2,1,1,0]
解释:
5 的右侧有 2 个更小的元素 (2 和 1).
2 的右侧仅有 1 个更小的元素 (1).
6 的右侧有 1 个更小的元素 (1).
1 的右侧有 0 个更小的元素.
想法
二叉树
从后往前遍历并插入二叉树。
「后边的数」在树靠近根节点的地方,意思说当树生成时,不会有在数组里比它靠前的数影响它。
在节点加入属性count,表示左子树的个数。
对于任一个节点,首先它肯定是叶子结点,因为刚刚插入到它。
那么比他小的数,就是它到根节点的距离加上根节点的左子数个数。
换言之这个节点肯定是在右子数的才行,因为这样才能保证比它大,还在前边
ok 看代码
Java代码
package daily;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CountSmaller {
public List<Integer> countSmaller(int[] nums) {
Integer [] res=new Integer[nums.length];
Arrays.fill(res,0);
List<Integer> list = new ArrayList<>();
TreeNode root = null;
for (int i = nums.length - 1; i >= 0; i--) {
root = insert(root, new TreeNode(nums[i]), res, i);
}
return Arrays.asList(res);
}
public TreeNode insert(TreeNode root,TreeNode node,Integer [] res,int i){
if(root==null){
root=node;
return root;
}
if(root.val>=node.val){
root.count++;
root.left=insert(root.left,node,res,i);
}
else {
res[i]+=root.count+1;
root.right=insert(root.right,node,res,i);
}
return root;
}
public static void main(String[] args){
CountSmaller countSmaller=new CountSmaller();
int[] nums= {5,2,6,1};
List<Integer>res=countSmaller.countSmaller(nums);
System.out.println(res.toString());
}
}
class TreeNode {
int val;
int count;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
left = null;
right = null;
count = 0;
}
}