Count of Smaller Numbers After Self
https://leetcode.com/problems/count-of-smaller-numbers-after-self/description/
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].
Thoughts
问比它的数小的个数,可以想到BST中从root到它所有要往左的节点数目和路径上每个节点的左子树数目的和。
节点中除了存值,还存左子树节点数。每次插入一个新节点到左边时,更新parent的这个值
问右边比小的个数,那就从右往左建树,树中即所有在它右边的数
有数重复的情况。因此还要一个dup, 默认应该为1.
Code
class Solution {
struct TreeNode {
TreeNode *left, *right;
int val, scount, dup;
TreeNode(int x) : val(x), scount(0), dup(1), left(NULL), right(NULL) {}
};
public:
vector<int> countSmaller(vector<int>& nums) {
int n = nums.size();
vector<int> res(n, 0);
if (n == 0) return res;
TreeNode* root = new TreeNode(nums[n - 1]);
for (int i = n - 2; i >= 0; i--) {
int scount = 0;
insert(root, nums[i], scount);
res[i] = scount;
}
return res;
}
private:
void insert(TreeNode *node, int num, int& scount) {
if (num < node->val) {
++node->scount;
if (!node->left) {
node->left = new TreeNode(num);
} else {
insert(node->left, num, scount);
}
} else if (num > node->val) {
scount += node->scount + node->dup;
if (!node->right) {
node->right = new TreeNode(num);
} else {
insert(node->right, num, scount);
}
} else {
scount += node->scount;
++node->dup;
}
}
};
class Solution {
class TreeNode {
int val, smallerCount, dup = 1;
TreeNode left, right;
TreeNode(int val, int smallerCount) {
this.val = val;
this.smallerCount = smallerCount;
}
}
int count = 0;
private TreeNode insert(TreeNode node, int num, int smallerCount) {
if (node == null) {
count = smallerCount;
return new TreeNode(num, 0);
}
if (num < node.val) {
node.smallerCount++;
node.left = insert(node.left, num, smallerCount);
} else if (num > node.val) {
node.right = insert(node.right, num, smallerCount + node.smallerCount + node.dup);
} else {
node.dup++;
count = smallerCount + node.smallerCount;
}
return node;
}
public List<Integer> countSmaller(int[] nums) {
List<Integer> res = new ArrayList<>();
TreeNode root = null;
for (int i = nums.length - 1; i >= 0; i--) {
count = 0;
root = insert(root, nums[i], 0);
res.add(0, count);
}
return res;
}
}
Analysis
Errors:
忘了加当node.val == nums[i]时的smallerCount.
树balance时, 时间复杂度O(NlgN).
Ver.2
Iterative建树
class Solution {
class TreeNode {
int val, dup, smallerCount;
TreeNode left, right;
TreeNode(int val) {
this.val = val;
dup = 1;
smallerCount = 0;
}
}
private int add(TreeNode root, int num) {
int res = 0;
TreeNode node = root;
while (node != null) {
if (num < node.val) {
node.smallerCount++;
if (node.left == null) {
node.left = new TreeNode(num);
break;
} else {
node = node.left;
}
} else if (num > node.val) {
res += node.smallerCount + node.dup;
if (node.right == null) {
node.right = new TreeNode(num);
break;
} else {
node = node.right;
}
} else {
res += node.smallerCount;
node.dup++;
break;
}
}
return res;
}
public List<Integer> countSmaller(int[] nums) {
List<Integer> res = new ArrayList<>();
if (nums.length == 0) {
return res;
}
TreeNode root = new TreeNode(nums[nums.length - 1]);
res.add(0);
for (int i = nums.length - 2; i >= 0; i--) {
res.add(0, add(root, nums[i]));
}
return res;
}
}
Last updated
Was this helpful?