diff --git a/solution/0300-0399/0379.Design Phone Directory/README.md b/solution/0300-0399/0379.Design Phone Directory/README.md index f553a7940cdf3..1b671e581f3d3 100644 --- a/solution/0300-0399/0379.Design Phone Directory/README.md +++ b/solution/0300-0399/0379.Design Phone Directory/README.md @@ -73,7 +73,17 @@ directory.check(2); -### 方法一 +### 方法一:哈希表 + +我们可以使用一个哈希集合 `available` 来存储未被分配的电话号码,初始时,哈希表中存储的是 `[0, 1, 2, ..., maxNumbers - 1]`。 + +调用 `get` 方法时,我们从 `available` 中取出一个未被分配的电话号码,如果 `available` 为空,则返回 `-1`。时间复杂度 $O(1)$。 + +调用 `check` 方法时,我们只需要判断 `number` 是否在 `available` 中即可。时间复杂度 $O(1)$。 + +调用 `release` 方法时,我们将 `number` 添加到 `available` 中。时间复杂度 $O(1)$。 + +空间复杂度 $O(n)$,其中 $n$ 是 `maxNumbers` 的值。 @@ -81,35 +91,20 @@ directory.check(2); ```python class PhoneDirectory: + def __init__(self, maxNumbers: int): - """ - Initialize your data structure here - @param maxNumbers - The maximum numbers that can be stored in the phone directory. - """ - self.provided = [False] * maxNumbers + self.available = set(range(maxNumbers)) def get(self) -> int: - """ - Provide a number which is not assigned to anyone. - @return - Return an available number. Return -1 if none is available. - """ - for i in range(len(self.provided)): - if not self.provided[i]: - self.provided[i] = True - return i - return -1 + if not self.available: + return -1 + return self.available.pop() def check(self, number: int) -> bool: - """ - Check if a number is available or not. - """ - return not self.provided[number] + return number in self.available def release(self, number: int) -> None: - """ - Recycle or release a number. - """ - self.provided[number] = False + self.available.add(number) # Your PhoneDirectory object will be instantiated and called as such: @@ -123,39 +118,29 @@ class PhoneDirectory: ```java class PhoneDirectory { + private Set available = new HashSet<>(); - private boolean[] provided; - - /** - Initialize your data structure here - @param maxNumbers - The maximum numbers that can be stored in the phone directory. - */ public PhoneDirectory(int maxNumbers) { - provided = new boolean[maxNumbers]; + for (int i = 0; i < maxNumbers; ++i) { + available.add(i); + } } - /** - Provide a number which is not assigned to anyone. - @return - Return an available number. Return -1 if none is available. - */ public int get() { - for (int i = 0; i < provided.length; ++i) { - if (!provided[i]) { - provided[i] = true; - return i; - } + if (available.isEmpty()) { + return -1; } - return -1; + int x = available.iterator().next(); + available.remove(x); + return x; } - /** Check if a number is available or not. */ public boolean check(int number) { - return !provided[number]; + return available.contains(number); } - /** Recycle or release a number. */ public void release(int number) { - provided[number] = false; + available.add(number); } } @@ -168,6 +153,127 @@ class PhoneDirectory { */ ``` +#### C++ + +```cpp +class PhoneDirectory { +public: + PhoneDirectory(int maxNumbers) { + for (int i = 0; i < maxNumbers; ++i) { + available.insert(i); + } + } + + int get() { + if (available.empty()) { + return -1; + } + int x = *available.begin(); + available.erase(x); + return x; + } + + bool check(int number) { + return available.contains(number); + } + + void release(int number) { + available.insert(number); + } + +private: + unordered_set available; +}; + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * PhoneDirectory* obj = new PhoneDirectory(maxNumbers); + * int param_1 = obj->get(); + * bool param_2 = obj->check(number); + * obj->release(number); + */ +``` + +#### Go + +```go +type PhoneDirectory struct { + available map[int]bool +} + +func Constructor(maxNumbers int) PhoneDirectory { + available := make(map[int]bool) + for i := 0; i < maxNumbers; i++ { + available[i] = true + } + return PhoneDirectory{available} +} + +func (this *PhoneDirectory) Get() int { + for k := range this.available { + delete(this.available, k) + return k + } + return -1 +} + +func (this *PhoneDirectory) Check(number int) bool { + _, ok := this.available[number] + return ok +} + +func (this *PhoneDirectory) Release(number int) { + this.available[number] = true +} + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * obj := Constructor(maxNumbers); + * param_1 := obj.Get(); + * param_2 := obj.Check(number); + * obj.Release(number); + */ +``` + +#### TypeScript + +```ts +class PhoneDirectory { + private available: Set = new Set(); + + constructor(maxNumbers: number) { + for (let i = 0; i < maxNumbers; ++i) { + this.available.add(i); + } + } + + get(): number { + const [x] = this.available; + if (x === undefined) { + return -1; + } + this.available.delete(x); + return x; + } + + check(number: number): boolean { + return this.available.has(number); + } + + release(number: number): void { + this.available.add(number); + } +} + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * var obj = new PhoneDirectory(maxNumbers) + * var param_1 = obj.get() + * var param_2 = obj.check(number) + * obj.release(number) + */ +``` + diff --git a/solution/0300-0399/0379.Design Phone Directory/README_EN.md b/solution/0300-0399/0379.Design Phone Directory/README_EN.md index 0e45d26b81770..bd22f9e773073 100644 --- a/solution/0300-0399/0379.Design Phone Directory/README_EN.md +++ b/solution/0300-0399/0379.Design Phone Directory/README_EN.md @@ -67,7 +67,17 @@ phoneDirectory.check(2); // Number 2 is available again, return true. -### Solution 1 +### Solution 1: Hash Table + +We can use a hash set `available` to store unallocated phone numbers. Initially, the hash set contains `[0, 1, 2, ..., maxNumbers - 1]`. + +When the `get` method is called, we take an unallocated phone number from `available`. If `available` is empty, we return `-1`. The time complexity is $O(1)$. + +When the `check` method is called, we just need to check whether `number` is in `available`. The time complexity is $O(1)$. + +When the `release` method is called, we add `number` to `available`. The time complexity is $O(1)$. + +The space complexity is $O(n)$, where $n$ is the value of `maxNumbers`. @@ -75,35 +85,20 @@ phoneDirectory.check(2); // Number 2 is available again, return true. ```python class PhoneDirectory: + def __init__(self, maxNumbers: int): - """ - Initialize your data structure here - @param maxNumbers - The maximum numbers that can be stored in the phone directory. - """ - self.provided = [False] * maxNumbers + self.available = set(range(maxNumbers)) def get(self) -> int: - """ - Provide a number which is not assigned to anyone. - @return - Return an available number. Return -1 if none is available. - """ - for i in range(len(self.provided)): - if not self.provided[i]: - self.provided[i] = True - return i - return -1 + if not self.available: + return -1 + return self.available.pop() def check(self, number: int) -> bool: - """ - Check if a number is available or not. - """ - return not self.provided[number] + return number in self.available def release(self, number: int) -> None: - """ - Recycle or release a number. - """ - self.provided[number] = False + self.available.add(number) # Your PhoneDirectory object will be instantiated and called as such: @@ -117,39 +112,29 @@ class PhoneDirectory: ```java class PhoneDirectory { + private Set available = new HashSet<>(); - private boolean[] provided; - - /** - Initialize your data structure here - @param maxNumbers - The maximum numbers that can be stored in the phone directory. - */ public PhoneDirectory(int maxNumbers) { - provided = new boolean[maxNumbers]; + for (int i = 0; i < maxNumbers; ++i) { + available.add(i); + } } - /** - Provide a number which is not assigned to anyone. - @return - Return an available number. Return -1 if none is available. - */ public int get() { - for (int i = 0; i < provided.length; ++i) { - if (!provided[i]) { - provided[i] = true; - return i; - } + if (available.isEmpty()) { + return -1; } - return -1; + int x = available.iterator().next(); + available.remove(x); + return x; } - /** Check if a number is available or not. */ public boolean check(int number) { - return !provided[number]; + return available.contains(number); } - /** Recycle or release a number. */ public void release(int number) { - provided[number] = false; + available.add(number); } } @@ -162,6 +147,127 @@ class PhoneDirectory { */ ``` +#### C++ + +```cpp +class PhoneDirectory { +public: + PhoneDirectory(int maxNumbers) { + for (int i = 0; i < maxNumbers; ++i) { + available.insert(i); + } + } + + int get() { + if (available.empty()) { + return -1; + } + int x = *available.begin(); + available.erase(x); + return x; + } + + bool check(int number) { + return available.contains(number); + } + + void release(int number) { + available.insert(number); + } + +private: + unordered_set available; +}; + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * PhoneDirectory* obj = new PhoneDirectory(maxNumbers); + * int param_1 = obj->get(); + * bool param_2 = obj->check(number); + * obj->release(number); + */ +``` + +#### Go + +```go +type PhoneDirectory struct { + available map[int]bool +} + +func Constructor(maxNumbers int) PhoneDirectory { + available := make(map[int]bool) + for i := 0; i < maxNumbers; i++ { + available[i] = true + } + return PhoneDirectory{available} +} + +func (this *PhoneDirectory) Get() int { + for k := range this.available { + delete(this.available, k) + return k + } + return -1 +} + +func (this *PhoneDirectory) Check(number int) bool { + _, ok := this.available[number] + return ok +} + +func (this *PhoneDirectory) Release(number int) { + this.available[number] = true +} + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * obj := Constructor(maxNumbers); + * param_1 := obj.Get(); + * param_2 := obj.Check(number); + * obj.Release(number); + */ +``` + +#### TypeScript + +```ts +class PhoneDirectory { + private available: Set = new Set(); + + constructor(maxNumbers: number) { + for (let i = 0; i < maxNumbers; ++i) { + this.available.add(i); + } + } + + get(): number { + const [x] = this.available; + if (x === undefined) { + return -1; + } + this.available.delete(x); + return x; + } + + check(number: number): boolean { + return this.available.has(number); + } + + release(number: number): void { + this.available.add(number); + } +} + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * var obj = new PhoneDirectory(maxNumbers) + * var param_1 = obj.get() + * var param_2 = obj.check(number) + * obj.release(number) + */ +``` + diff --git a/solution/0300-0399/0379.Design Phone Directory/Solution.cpp b/solution/0300-0399/0379.Design Phone Directory/Solution.cpp new file mode 100644 index 0000000000000..fea0995b278c3 --- /dev/null +++ b/solution/0300-0399/0379.Design Phone Directory/Solution.cpp @@ -0,0 +1,36 @@ +class PhoneDirectory { +public: + PhoneDirectory(int maxNumbers) { + for (int i = 0; i < maxNumbers; ++i) { + available.insert(i); + } + } + + int get() { + if (available.empty()) { + return -1; + } + int x = *available.begin(); + available.erase(x); + return x; + } + + bool check(int number) { + return available.contains(number); + } + + void release(int number) { + available.insert(number); + } + +private: + unordered_set available; +}; + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * PhoneDirectory* obj = new PhoneDirectory(maxNumbers); + * int param_1 = obj->get(); + * bool param_2 = obj->check(number); + * obj->release(number); + */ \ No newline at end of file diff --git a/solution/0300-0399/0379.Design Phone Directory/Solution.go b/solution/0300-0399/0379.Design Phone Directory/Solution.go new file mode 100644 index 0000000000000..7df5601d90a62 --- /dev/null +++ b/solution/0300-0399/0379.Design Phone Directory/Solution.go @@ -0,0 +1,36 @@ +type PhoneDirectory struct { + available map[int]bool +} + +func Constructor(maxNumbers int) PhoneDirectory { + available := make(map[int]bool) + for i := 0; i < maxNumbers; i++ { + available[i] = true + } + return PhoneDirectory{available} +} + +func (this *PhoneDirectory) Get() int { + for k := range this.available { + delete(this.available, k) + return k + } + return -1 +} + +func (this *PhoneDirectory) Check(number int) bool { + _, ok := this.available[number] + return ok +} + +func (this *PhoneDirectory) Release(number int) { + this.available[number] = true +} + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * obj := Constructor(maxNumbers); + * param_1 := obj.Get(); + * param_2 := obj.Check(number); + * obj.Release(number); + */ \ No newline at end of file diff --git a/solution/0300-0399/0379.Design Phone Directory/Solution.java b/solution/0300-0399/0379.Design Phone Directory/Solution.java index b4afc45848139..9fcbbb41d0c45 100644 --- a/solution/0300-0399/0379.Design Phone Directory/Solution.java +++ b/solution/0300-0399/0379.Design Phone Directory/Solution.java @@ -1,37 +1,27 @@ class PhoneDirectory { + private Set available = new HashSet<>(); - private boolean[] provided; - - /** - Initialize your data structure here - @param maxNumbers - The maximum numbers that can be stored in the phone directory. - */ public PhoneDirectory(int maxNumbers) { - provided = new boolean[maxNumbers]; + for (int i = 0; i < maxNumbers; ++i) { + available.add(i); + } } - /** - Provide a number which is not assigned to anyone. - @return - Return an available number. Return -1 if none is available. - */ public int get() { - for (int i = 0; i < provided.length; ++i) { - if (!provided[i]) { - provided[i] = true; - return i; - } + if (available.isEmpty()) { + return -1; } - return -1; + int x = available.iterator().next(); + available.remove(x); + return x; } - /** Check if a number is available or not. */ public boolean check(int number) { - return !provided[number]; + return available.contains(number); } - /** Recycle or release a number. */ public void release(int number) { - provided[number] = false; + available.add(number); } } diff --git a/solution/0300-0399/0379.Design Phone Directory/Solution.py b/solution/0300-0399/0379.Design Phone Directory/Solution.py index 47fc2dd96eda9..bf3ed3c586544 100644 --- a/solution/0300-0399/0379.Design Phone Directory/Solution.py +++ b/solution/0300-0399/0379.Design Phone Directory/Solution.py @@ -1,33 +1,18 @@ class PhoneDirectory: + def __init__(self, maxNumbers: int): - """ - Initialize your data structure here - @param maxNumbers - The maximum numbers that can be stored in the phone directory. - """ - self.provided = [False] * maxNumbers + self.available = set(range(maxNumbers)) def get(self) -> int: - """ - Provide a number which is not assigned to anyone. - @return - Return an available number. Return -1 if none is available. - """ - for i in range(len(self.provided)): - if not self.provided[i]: - self.provided[i] = True - return i - return -1 + if not self.available: + return -1 + return self.available.pop() def check(self, number: int) -> bool: - """ - Check if a number is available or not. - """ - return not self.provided[number] + return number in self.available def release(self, number: int) -> None: - """ - Recycle or release a number. - """ - self.provided[number] = False + self.available.add(number) # Your PhoneDirectory object will be instantiated and called as such: diff --git a/solution/0300-0399/0379.Design Phone Directory/Solution.ts b/solution/0300-0399/0379.Design Phone Directory/Solution.ts new file mode 100644 index 0000000000000..06ec49e02df18 --- /dev/null +++ b/solution/0300-0399/0379.Design Phone Directory/Solution.ts @@ -0,0 +1,34 @@ +class PhoneDirectory { + private available: Set = new Set(); + + constructor(maxNumbers: number) { + for (let i = 0; i < maxNumbers; ++i) { + this.available.add(i); + } + } + + get(): number { + const [x] = this.available; + if (x === undefined) { + return -1; + } + this.available.delete(x); + return x; + } + + check(number: number): boolean { + return this.available.has(number); + } + + release(number: number): void { + this.available.add(number); + } +} + +/** + * Your PhoneDirectory object will be instantiated and called as such: + * var obj = new PhoneDirectory(maxNumbers) + * var param_1 = obj.get() + * var param_2 = obj.check(number) + * obj.release(number) + */