LeetCode #315 Count of Smaller Numbers After Self

来源:互联网 发布:成绩管理系统c程序软件 编辑:程序博客网 时间:2024/06/04 19:54

LeetCode #315 Count of Smaller Numbers After Self

问题描述
给出一个整数序列,求解在这个序列中每个数字右边有多少个数字比当前数字小。
例子:

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 [2, 1, 1, 0]

算法分析
有两种思路:

  • 思路一:平衡树
    这是很简单也很暴力的思路。将nums从右往左依次插入平衡树中,每次都找出比当前这个数字小的数字有多少个,就解决了。时间复杂度:O(n log n)

  • 思路二:树状数组
    这个相对复杂一点。首先,我们需要将nums离散化,即使得最大的数字不那么大。然后,设置一个树状数组Tree,大小为最大的数字,值全为0。
    然后将nums从右往左枚举过去,每次将Tree[nums[i]]的前缀和添加到对应位置的答案,并把T[nums[i]]的值加一。
    求前缀和、树状数组中的数字修改,时间复杂度都是O(logn)的,离散化即排序的时间复杂度为O(nlogn),故总时间复杂度为O(nlogn)

结论

  • 这题我是用平衡树写的,理由是我很久没有写过平衡树了,只知道思路,已经完全不会写了。所以我就参考了别人的平衡树(Splay)模板,又对平衡树重新学了一番,既算是复习,也是学习。由于代码是参考别人的模板来的,就不贴上来了。
  • 关于树状数组,这题似乎数据很水,只需要将nums中的所有数字都减去里面的最小值,就可以用树状数组暴力过去了,懒得写离散化的话就这样水吧。
  • 其实我一直在思考有没有O(n)的做法,或者同时间复杂度下更简单的实现方法(因为我不会写平衡树啊,也不想写离散化……懒癌)。但是我都没有想到,希望评论中能有大神指点一下。
0 0
原创粉丝点击