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].html
Example:node
Input: [5,2,6,1] Output: [2,1,1,0] Explanation: 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.
給定一個整數數組 nums,按要求返回一個新數組 counts。數組 counts 有該性質: counts[i] 的值是 nums[i] 右側小於 nums[i] 的元素的數量。python
示例:git
輸入: [5,2,6,1] 輸出: [2,1,1,0] 解釋: 5 的右側有 2 個更小的元素 (2 和 1). 2 的右側僅有 1 個更小的元素 (1). 6 的右側有 1 個更小的元素 (1). 1 的右側有 0 個更小的元素.
# -*- coding: utf-8 -*- # @Author: 何睿 # @Create Date: 2019-02-20 13:55:15 # @Last Modified by: 何睿 # @Last Modified time: 2019-02-21 11:48:51 # python 內部二分搜索庫 import bisect # 二叉搜索樹的節點 class Node: def __init__(self, value=None): # 節點的值 self.value = value # 二叉搜索樹不存儲重複節點,咱們用 count 來存值出現的次數 self.count = 1 # 比當前元素值小的元素個數 self.smaller = 0 # 左子樹 self.left_child = None # 右子樹 self.right_child = None class BinarySearchTree: def __init__(self): self.root = None def insert(self, value): if self.root == None: self.root = Node(value) return 0 else: return self._insert(value, self.root) def _insert(self, value, node): # 若是當前須要插入的值比當前節點的值小 if value < node.value: # node.smaller 自增一次 node.smaller += 1 # 若是當前節點尚未左子樹 if node.left_child == None: # 建立一個新的節點 node.left_child = Node(value) # 返回 0 表示比當前插入元素還小的元素個數爲 0 return 0 else: # 不然將當前元素插入到當前節點的左子樹 return self._insert(value, node.left_child) # 若是當前須要插入的值比當前節點的值大 elif value > node.value: # smaller 表示當前節點鏈接的左子樹的全部節點個數 # 左子樹的全部節點值必定比當前節點小 # 因爲樹是動態建立的,所以比 value 值小的節點在當前節點的左子樹和當前節點的右子樹的左子樹中 smaller = node.count + node.smaller # 若是當前節點尚未右子樹 if node.right_child == None: # 建立一個新的節點 node.right_child = Node(value) # 返回 smaller return smaller else: # 若是有右子樹,說明當前值不只比當前節點的左子樹的節點值大 # 有可能比當前節點的右子樹的左子樹節點大, # smaller 僅僅記錄了當前節點的左子樹 # 返回 smaller + 當前節點右子樹中比要插入的值小的元素個數 return smaller + self._insert(value, node.right_child) else: # 若是當前要插入的值已經在二叉搜索樹中,count 自增一次 node.count += 1 # 返回 node.smaller return node.smaller class Solution: # 第一種方法,咱們藉助二叉搜索樹實現 # 須要本身實現二叉搜索數 「只須要實現插入部分,查找和刪除在這裏用不到」 def countSmaller(self, nums: 'List[int]') -> 'List[int]': Tree = BinarySearchTree() res = [] for num in nums[::-1]: # 從後向前插入,每次插入一個值,返回樹中比當前元素小的元素的個數 res.append(Tree.insert(num)) # 由於咱們是從後面向前插入的,因此須要返回逆序的結果數組 return res[::-1] # 方法二,藉助python 二分搜索庫 def countSmaller2(self, nums: 'List[int]') -> 'List[int]': res, visited = [], [] for num in nums[::-1]: # num 插入位置的索引就是比他小的元素的個數 res.append(bisect.bisect_left(visited, num)) # 將 num 元素插入到 visited 數組中 # 這裏使用 insort_right 或者 insort_left 都可 bisect.insort_right(visited, num) # 返回逆序的結果數組 return res[::-1]