leetcode 2349. Design a Number Container System(python)

756 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

描述

Design a number container system that can do the following:

  • Insert or Replace a number at the given index in the system.
  • Return the smallest index for the given number in the system.

Implement the NumberContainers class:

  • NumberContainers() Initializes the number container system.
  • void change(int index, int number) Fills the container at index with the number. If there is already a number at that index, replace it.
  • int find(int number) Returns the smallest index for the given number, or -1 if there is no index that is filled by number in the system.

Example 1:

Input
["NumberContainers", "find", "change", "change", "change", "change", "find", "change", "find"]
[[], [10], [2, 10], [1, 10], [3, 10], [5, 10], [10], [1, 20], [10]]
Output
[null, -1, null, null, null, null, 1, null, 2]

Explanation
NumberContainers nc = new NumberContainers();
nc.find(10); // There is no index that is filled with number 10. Therefore, we return -1.
nc.change(2, 10); // Your container at index 2 will be filled with number 10.
nc.change(1, 10); // Your container at index 1 will be filled with number 10.
nc.change(3, 10); // Your container at index 3 will be filled with number 10.
nc.change(5, 10); // Your container at index 5 will be filled with number 10.
nc.find(10); // Number 10 is at the indices 1, 2, 3, and 5. Since the smallest index that is filled with 10 is 1, we return 1.
nc.change(1, 20); // Your container at index 1 will be filled with number 20. Note that index 1 was filled with 10 and then replaced with 20. 
nc.find(10); // Number 10 is at the indices 2, 3, and 5. The smallest index that is filled with 10 is 2. Therefore, we return 2.

Note:

1 <= index, number <= 109
At most 10^5 calls will be made in total to change and find.

解析

根据题意,设计一个可以执行以下操作的数字容器系统:

  • 在系统中的给定索引处插入或替换一个数字。
  • 返回系统中给定数字的最小索引。

实现 NumberContainers 类:

  • NumberContainers() 初始化数字容器系统。
  • void change(int index, int number) 用数字填充索引处的容器。 如果该索引处已经有一个数字,请将其替换。
  • int find(int number) 返回给定数字的最小索引,如果系统中没有由数字填充的索引,则返回 -1。

这道题的关键就在于 change 和 find 的方法要调用 10^5 ,所以每个函数的时间复杂度都必须要在 O(NlogN) 以下,分别对两个函数进行解析:

而 find 要找出某个数字的最小索引,这就需要我们事先保存好该数字对应的索引集合,而且为了最快取出最小的索引,这个集合应该是有序集合,所以我们用字典结合有序集合保存某个数字对应的索引集合,定义为 n2s ,这样我们将 find 的时间复杂度降到了 O(1) ,空间复杂度为 O(1) 。

change 要对某个索引的值进行改变,自然用字典进行填充和修改是最快的,定义为 i2n ;但是因为要改变之前索引对应的值 old ,所以要将 n2s[old] 对应的索引删除,然后更新 i2n[index] 为 number ,n2s[number] 将最新的索引收录,因为每次加入新的索引要进行排序,所以时间复杂度主要消耗在了有序集合的排序中,时间复杂度为 O(nlogN) ,空间复杂度为 O(N) 。

解答

from sortedcontainers import  SortedSet
class NumberContainers(object):

    def __init__(self):
        self.i2n = collections.defaultdict()
        self.n2s = collections.defaultdict(SortedSet)

    def change(self, index, number):
        if index in self.i2n:
            n = self.i2n[index]
            self.n2s[n].remove(index)
        self.i2n[index] = number
        self.n2s[number].add(index)

    def find(self, number):
        if number in self.n2s and len(self.n2s[number]) > 0:
            return self.n2s[number][0]
        return -1

运行结果

44 / 44 test cases passed.
Status: Accepted
Runtime: 2168 ms
Memory Usage: 62.1 MB

原题链接

leetcode.com/contest/biw…

您的支持是我最大的动力