Count of Smaller Numbers After Self -- LeetCode

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(nlogn)复杂度算法。

将数组排序然后构建二叉搜索树。一开始二叉搜索树上的节点都标记为未处理过。然后我们从所给的nums数组的最后一个数倒着向前遍历,依次将每一个数在二叉搜索树中对应的节点标记为处理过,然后返回二叉搜索树中已经被标记为处理过,且小于该值的个数。

具体实现中,我们在每一个节点中设置一个count变量,计数以该节点为根节点的子树中已经被标记为处理过的节点个数,初始为0。之后算法运行过程中不断更新该值并通过该值更快地求解。本质上来说这是一个线段树的应用。

当我们要求二叉搜索树中有多少被处理过的节点值小于所给的值时,有三种情况:

  • 所给的值是当前子树的根节点。则小于它的数只可能在左子树中,因此返回根节点左孩子的count值。
  • 所给的值在当前子树的左子树中。则小于它的数只可能在左子树中,因此递归求解,返回左子树中被处理过且小于所给值的节点个数。
  • 所给的值在当前子树的右子树中。则小于它的数可能在左子树中或者是该根节点,或者在右子树中。因此递归求解,返回左子树和根节点中被处理过且小于所给值的节点个数加上右子树中被处理过且小于所给值的节点个数。

二叉搜索树的构建O(n),二叉搜索树的单次查找更新操作O(logn)。 总复杂度为O(n) + O(nlogn) = O(nlogn)

 1 class treeNode {
 2 public:
 3     int val, count;
 4     treeNode *left, *right;
 5     treeNode(int v) : val(v), count(0), left(NULL), right(NULL) {}
 6 };
 7 class Solution {
 8 public:
 9     //convert a sortedArray to a binary search tree and return a pointer to its root node
10     treeNode* buildTree(vector<int>& sortedArray, int left, int right) {
11         if (right < left) return NULL;
12         int mid = left + (right - left) / 2;
13         treeNode* cur = new treeNode(sortedArray[mid]);
14         cur->left = buildTree(sortedArray, left, mid - 1);
15         cur->right = buildTree(sortedArray, mid + 1, right);
16         return cur;
17     }
18     //count numbers in this binary search tree that were processed and are less than the target
19     int update(treeNode* node, int target) {
20         if (node == NULL) return -1;
21         if (node->val == target) {
22             node->count++;
23             return node->left ? node->left->count : 0;
24         }
25         else if (node->val < target) {
26             int lessCount = node->count - node->right->count;
27             int rightCount = update(node->right, target);
28             node->count++;
29             return lessCount + rightCount;
30         }
31         else {
32             int leftCount = update(node->left, target);
33             node->count++;
34             return leftCount;
35         }
36     }
37     vector<int> countSmaller(vector<int>& nums) {
38         vector<int> sortedArray = nums;
39         sort(sortedArray.begin(), sortedArray.end(), less<int>());
40         treeNode* node = buildTree(sortedArray, 0, sortedArray.size() - 1);
41         vector<int> res(nums.size());
42         for (int i = nums.size() - 1; i >= 0; i--)
43             res[i] = update(node, nums[i]);
44         return res;
45     }
46 };
时间: 2024-10-13 04:23:34

Count of Smaller Numbers After Self -- LeetCode的相关文章

[LeetCode][JavaScript]Count of Smaller Numbers After Self

Count of Smaller Numbers After Self 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,

leetcode Count of Smaller Numbers After Self

题目连接 https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 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]$

剑指Offer 面试题36:数组中的逆序对及其变形(Leetcode 315. Count of Smaller Numbers After Self)题解

剑指Offer 面试题36:数组中的逆序对 题目:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 例如, 在数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6),(7,5),(7,4),(6,4)和(5,4),输出5. 提交网址: http://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188 或 htt

【Leetcode】Count of Smaller Numbers After Self

题目链接:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: 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 righ

[LeetCode] Count of Smaller Numbers After Self 计算后面较小数字的个数

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

leetcode 315. Count of Smaller Numbers After Self

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

第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树

Leetcode315 题意很简单,给定一个序列,求每一个数的右边有多少小于它的树. O(n^2)的算法是显而易见的. 用普通的线段树可以优化到O(nlogn) 我们可以直接套用主席树的模板. 主席树的功能是什么呢? 其实就是一句话. 原序列a的子序列a[l,r]在a排序后的序列b的子序列[L,R]中的个数. 显然本题只用到了主席树的一小部分功能. const int N = 100000 + 5; int a[N], b[N], rt[N * 20], ls[N * 20], rs[N * 2

[email&#160;protected] [315/215] Count of Smaller Numbers After Self / Kth Largest Element in an Array (BST)

https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 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

Count of Smaller Numbers After Self

题目: 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