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].
解释:
给一个数组,要求找到这个数组之后的所有比当前小的值
思考:
最初的想法是用单调栈来实现,实际就是查找当前的这个数字在目前排第几,然后把比他大的位置都加一,栈里面存的是下标,然后如果目前值比栈顶小,就pop,加一,然后重复,直到找到位置,这样的时间复杂度是On2的,最坏情况是一个递减序列,每次都要遍历所有。 更巧妙的做法其实是直接排序,记录原来的下标和排序之后的下标的关系,然后排序之后的下标就是比他小的数字的个数。时间是n2,插入排序 继续优化,有没有既能知道顺序,插入还是O1的办法呢,其实就是二叉搜索树了。这才是这个题真正想考察的点,实现一个二叉搜索树,每个点都从跟节点开始找,比较logn次一定能找到自己的位置,总时间就优化到nlogn了。
答案:
# 定义一个树的节点类
class TreeNode(object):
def __init__(self, val):
self.left = None
self.right = None
self.val = val # 节点值
self.count = 0 # 左子树节点数量
class Solution(object):
def countSmaller(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
length = len(nums)
root = None
# 结果集
res = [0 for _ in range(length)]
# nums 反序加入搜索树
for i in reversed(range(length)):
root = self.insertNode(root, nums[i], res, i)
return res
# 往二叉搜索树中插入新的节点
def insertNode(self, root, val, res, res_index):
if root == None:
root = TreeNode(val)
elif val <= root.val: # 小于当前节点值则放入左子树
# root 的左侧节点数量值 +1
root.count += 1
root.left = self.insertNode(root.left, val, res, res_index)
elif val > root.val: # 大于当前节点值则放入右子树
# 计算题目所求的结果
res[res_index] += root.count + 1
root.right = self.insertNode(root.right, val, res, res_index)
return root