【问题标题】:Count greater elements to the right of self在 self 的右侧计算更大的元素
【发布时间】:2018-06-30 11:50:59
【问题描述】:

下面给出的这个问题让我发疯。如果有人可以提供帮助,请。

“给定一个包含 'n' 个元素的数组 Num,返回一个长度为 'n' 的数组 A,其中 A[i] 在初始数组的右侧包含大于 Num[i] 的元素数”

我看到了一个 SO 答案 here,但它包含 O(n^2) 的解决方案。我需要 O(nlogn) 的解决方案。

我有“计算自身左侧的较小元素”的解决方案。但是修改它并没有给我所需的解决方案(请参阅下面的代码)。

任何帮助表示赞赏:)

class BinarySearchTreeNode(object):
   def __init__(self, val):
    self.val = val
    self.left = None
    self.right = None
    self.count = 1
    self.leftTreeSize = 0

class BinarySearchTree(object):
   def __init__(self):
    self.root = None
  
   def insert(self, val, root):
    if not root:
        self.root = BinarySearchTreeNode(val)
        return 0

    if val == root.val:
        root.count += 1
        return root.leftTreeSize

    if val < root.val:
        root.leftTreeSize += 1

        if not root.left:
            root.left = BinarySearchTreeNode(val)
            return 0
        return self.insert(val, root.left)

    if not root.right:
        root.right = BinarySearchTreeNode(val)
        return root.count + root.leftTreeSize

    return root.count + root.leftTreeSize + self.insert(val, root.right)

class Solution(object):
  def countSmaller(self, nums):
    
    tree = BinarySearchTree()
    return [
        tree.insert(nums[i], tree.root)
        for i in range(len(nums) - 1, -1, -1)
    ][::-1]

print(Solution().countSmaller(nums = [1, 4, 2, 7]))

例子:

给定数组 [10, 7, 2, 6, 5]

那么从小到右的count数组是[4, 3, 0, 1, 0]

大于左计数的数组为 [0, 1, 2, 2, 3]

希望这会有所帮助...

【问题讨论】:

  • 还没有检查过你的代码,但是如果你能解决“将较小的元素计数到 self 的左边”,那么这不可行吗? (1) O(N) 以相反的顺序创建数组 Num2 = Num 与否定值。 (2) O(NlogN) 通过在 Num2 中计算 self 左侧的较小元素来创建数组 A2。 (3) O(N) 通过反转A2创建数组A。
  • 听不懂你想说什么。做一个伪代码解释一下。
  • 我无法理解你的问题,你能补充一个例子吗?
  • @WebOrNative 该问题已通过示例更新

标签: python-3.x data-structures binary-search-tree


【解决方案1】:

我不知道这是否是您正在寻找的解决方案,因为我假设您希望我修复您的代码,但可以这样处理:

num = [10, 7, 2, 6, 5]

mergeSort(num) 或 heapSort(num)。我不知道python是否内置了这些,或者您是否需要自己实现。但是mergeSort/heapSort吧,它的最差复杂度是O(nlog(n)。

sortedNum = [2,5,6,7,10]

answer=[ ]

for every number in Num: 
    binarySearch number in sortedNum and return its position
    answer.appened(position)
    delete item from sortedNum at position.

for循环本身的复杂度为O(n),循环内的二分查找复杂度为log(n)。所以这个函数的复杂度为 O(n log(n)),因为追加和删除需要 O(1)

这意味着排序+伪编码函数的总复杂度为O(2nlog(n)) = O(nlog(n))。

编辑:因为我弄错了,你想在 self 的左边计算更大的元素。

这里不需要排序!

num = [10,7,2,6,5]

排序编号 = [ ]

答案 = [ ]

for every number in Num:
    position = binarySearch number in sortedNum to which numbers its inbetween. 
    insert number into that position into sortedNum
    answer.append(len(num)-position)

【讨论】:

  • 这种方法很好。但我要求的是数组,它给出了“自身左侧更大元素的计数”。您的伪代码给出了正确的小元素计数。换句话说,我需要上面示例中提到的输出 [0, 1, 2, 2, 3]。
  • 你的伪代码不清楚。在第一行你的意思是返回哪个元素的位置???你能用数组[10,7,2,6,5解释一下]
  • 如果对中间的数字进行二进制搜索,那么如何使用两个位置。如果数字=7,那么它在 10 和 2 之间。如何在只使用一个位置的情况下获得两个位置。还是我错过了什么? 澄清一下
  • 所以返回当前数字应该存储的位置。使用数组 [10,7,2,6,5] 在第一次搜索中,您将添加 10,因为数组 sortedNum 为空,您只需将其添加到位置 0。在第二次搜索中,您将添加 7。因为数组 sortNum 有 [10]。您需要将它插入到空和数字 10 之间。在第四次搜索中,您将和 6。因为数组 sortNum 具有 [2,7,10]。您需要将其插入到位置 1,介于 2 和 7 之间。sortNum 的总长度为 3。所以 3-1 = 2。
  • 当我的意思是位置时,如果你让我们说 sortedNum = [1,1,1,2,3,4,5,5,5,5,6] 并且想加 5 并且你想要找到位置,该位置在最后一次出现 5 时插入它,即 9。哦顺便说一句,您可能希望将其插入位置 +1 到 sortedNum 而不是位置。
【解决方案2】:
class Node(object):
def __init__(self, val):
    self.val = val
    self.left = None
    self.right = None
    self.count = 1
    self.rightTreeSize = 0
    self.leftTreeSize = 0

class BinarySearchTree(object):
def __init__(self):
    self.root = None

def insert(self, val, root):
    if not root:
        self.root = Node(val)
        return 0

    if val == root.val:
        root.count += 1
        return root.rightTreeSize

    if val > root.val:
        root.rightTreeSize += 1

        if not root.right:
            root.right = Node(val)
            return 0
        return self.insert(val, root.right)

    if not root.left:
        root.left = Node(val)
        return root.count + root.rightTreeSize

    return root.count + root.rightTreeSize + self.insert(val, root.left)


class BinarySearchTree1(object):
def __init__(self):
    self.root = None

def insert(self, val, root):
    if not root:
        self.root = Node(val)
        return 0

    if val == root.val:
        root.count += 1
        return root.leftTreeSize

    if val < root.val:
        root.leftTreeSize += 1

        if not root.left:
            root.left = Node(val)
            return 0
        return self.insert(val, root.left)

    if not root.right:
        root.right = Node(val)
        return root.count + root.leftTreeSize

    return root.count + root.leftTreeSize + self.insert(val, root.right)



class Solution(object):
def countGreater(self):
    nums = [10, 7, 2, 6, 5]
    tree = BinarySearchTree()
    print([tree.insert(nums[i], tree.root) for i in range(0, len(nums))])

def countSmaller(self):
    nums = [10, 7, 2, 6, 5]        
    tree1 = BinarySearchTree1()
    print([tree1.insert(nums[i], tree1.root) for i in range(len(nums) - 1, -1, -1)][::-1])


Solution().countSmaller()
Solution().countGreater()

抱歉缩进问题无法调整markdown编辑器中的所有行。

以上代码返回“自身右侧较小元素的数量”和“自身左侧较大元素的数量”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多