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]
.
含义:针对一个数组,找到每一位的右面有多少个数小于它的值,没有的话就是0,返回数组
思路一:从后往前用二分插入法来倒排数组,后面的数字个数即为比当前数字小的数字
1 public List<Integer> countSmaller(int[] nums) { 2 int[] smaller = new int[nums.length]; 3 for(int i=nums.length-2; i>=0; i--) { 4 // 从后往前遍历nums,采用二分插入排序的方式,将数组进行降序排列 5 // 取出nums[i]后保存到temp,从i+1到末尾间找到nums[i]应该存在的位置(从i+1到末尾是降序排列),比如是left 6 int left = i+1; 7 int right = nums.length-1; 8 while (left<=right) { 9 int m = (left+right)/2; 10 if (nums[i] > nums[m]) right = m - 1; 11 else left = m + 1; 12 } 13 smaller[i] = nums.length - left; //left后面的所有数都比nums[i]小 14 int temp = nums[i]; 15 for(int j=i; j<right; j++) nums[j] = nums[j+1]; //把i和right之间的数据依次往前移动,空出right位置用于放置nums[i] 16 nums[right] = temp; 17 }
return Arrays.stream(smaller)
.boxed()
.collect(Collectors.toList());
21 }
方法二:
1 public class Solution { 2 private class TreeNode { 3 public int val; 4 public int count = 1; 5 public TreeNode left, right; 6 7 public TreeNode(int val) { 8 this.val = val; 9 } 10 } 11 12 public List<Integer> countSmaller(int[] nums) { 13 // 构造一棵二分搜索树,稍有不同的地方是我们需要加一个变量smaller来记录比当前节点值小的所有节点的个数,我们每插入一个节点,会判断其和根节点的大小, 14 // 如果新的节点值小于根节点值,则其会插入到左子树中,我们此时要增加根节点的smaller,并继续递归调用左子节点的insert。 15 // 如果节点值大于根节点值,则需要递归调用右子节点的insert并加上根节点的smaller,并加1 16 17 List<Integer> res = new ArrayList<>(); 18 if(nums == null || nums.length == 0) { 19 return res; 20 } 21 TreeNode root = new TreeNode(nums[nums.length - 1]); 22 res.add(0); 23 24 for(int i = nums.length - 2; i >= 0; i--) { 25 int count = addNode(root, nums[i]); 26 res.add(count); 27 } 28 29 Collections.reverse(res); 30 return res; 31 } 32 33 private int addNode(TreeNode root, int val) { 34 int curCount = 0; 35 while(true) { 36 if(val <= root.val) { 37 root.count++; // add the inversion count 38 if(root.left == null) { 39 root.left = new TreeNode(val); 40 break; 41 } else { 42 root = root.left; 43 } 44 } else { 45 curCount += root.count; 46 if(root.right == null) { 47 root.right = new TreeNode(val); 48 break; 49 } else { 50 root = root.right; 51 } 52 } 53 } 54 55 return curCount; 56 }