|
| 1 | +--- |
| 2 | +comments: true |
| 3 | +difficulty: 简单 |
| 4 | +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3491.Phone%20Number%20Prefix/README.md |
| 5 | +--- |
| 6 | + |
| 7 | +<!-- problem:start --> |
| 8 | + |
| 9 | +# [3491. Phone Number Prefix 🔒](https://leetcode.cn/problems/phone-number-prefix) |
| 10 | + |
| 11 | +[English Version](/solution/3400-3499/3491.Phone%20Number%20Prefix/README_EN.md) |
| 12 | + |
| 13 | +## 题目描述 |
| 14 | + |
| 15 | +<!-- description:start --> |
| 16 | + |
| 17 | +<p>You are given a string array <code>numbers</code> that represents phone numbers. Return <code>true</code> if no phone number is a prefix of any other phone number; otherwise, return <code>false</code>.</p> |
| 18 | + |
| 19 | +<p> </p> |
| 20 | +<p><strong class="example">Example 1:</strong></p> |
| 21 | + |
| 22 | +<div class="example-block"> |
| 23 | +<p><strong>Input:</strong> <span class="example-io">numbers = ["1","2","4","3"]</span></p> |
| 24 | + |
| 25 | +<p><strong>Output:</strong> <span class="example-io">true</span></p> |
| 26 | + |
| 27 | +<p><strong>Explanation:</strong></p> |
| 28 | + |
| 29 | +<p>No number is a prefix of another number, so the output is <code>true</code>.</p> |
| 30 | +</div> |
| 31 | + |
| 32 | +<p><strong class="example">Example 2:</strong></p> |
| 33 | + |
| 34 | +<div class="example-block"> |
| 35 | +<p><strong>Input:</strong> <span class="example-io">numbers = ["001","007","15","00153"]</span></p> |
| 36 | + |
| 37 | +<p><strong>Output:</strong> <span class="example-io">false</span></p> |
| 38 | + |
| 39 | +<p><strong>Explanation:</strong></p> |
| 40 | + |
| 41 | +<p>The string <code>"001"</code> is a prefix of the string <code>"00153"</code>. Thus, the output is <code>false</code>.</p> |
| 42 | +</div> |
| 43 | + |
| 44 | +<p> </p> |
| 45 | +<p><strong>Constraints:</strong></p> |
| 46 | + |
| 47 | +<ul> |
| 48 | + <li><code>2 <= numbers.length <= 50</code></li> |
| 49 | + <li><code>1 <= numbers[i].length <= 50</code></li> |
| 50 | + <li>All numbers contain only digits <code>'0'</code> to <code>'9'</code>.</li> |
| 51 | +</ul> |
| 52 | + |
| 53 | +<!-- description:end --> |
| 54 | + |
| 55 | +## 解法 |
| 56 | + |
| 57 | +<!-- solution:start --> |
| 58 | + |
| 59 | +### 方法一:排序 + 前缀判断 |
| 60 | + |
| 61 | +我们可以先对 $\textit{numbers}$ 数组按照字符串长度进行排序,然后遍历数组中的每一个字符串 $\textit{s}$,判断此前是否有字符串 $\textit{t}$ 是 $\textit{s}$ 的前缀,如果有,说明存在一个字符串是另一个字符串的前缀,返回 $\textit{false}$。如果遍历完所有字符串都没有找到前缀关系,返回 $\textit{true}$。 |
| 62 | + |
| 63 | +时间复杂度 $(n^2 \times m + n \times \log n)$,空间复杂度 $(m + \log n)$,其中 $n$ 是 $\textit{numbers}$ 数组的长度,而 $m$ 是 $\textit{numbers}$ 数组中字符串的平均长度。 |
| 64 | + |
| 65 | +<!-- tabs:start --> |
| 66 | + |
| 67 | +#### Python3 |
| 68 | + |
| 69 | +```python |
| 70 | +class Solution: |
| 71 | + def phonePrefix(self, numbers: List[str]) -> bool: |
| 72 | + numbers.sort(key=len) |
| 73 | + for i, s in enumerate(numbers): |
| 74 | + if any(s.startswith(t) for t in numbers[:i]): |
| 75 | + return False |
| 76 | + return True |
| 77 | +``` |
| 78 | + |
| 79 | +#### Java |
| 80 | + |
| 81 | +```java |
| 82 | +class Solution { |
| 83 | + public boolean phonePrefix(String[] numbers) { |
| 84 | + Arrays.sort(numbers, (a, b) -> Integer.compare(a.length(), b.length())); |
| 85 | + for (int i = 0; i < numbers.length; i++) { |
| 86 | + String s = numbers[i]; |
| 87 | + for (int j = 0; j < i; j++) { |
| 88 | + if (s.startsWith(numbers[j])) { |
| 89 | + return false; |
| 90 | + } |
| 91 | + } |
| 92 | + } |
| 93 | + return true; |
| 94 | + } |
| 95 | +} |
| 96 | +``` |
| 97 | + |
| 98 | +#### C++ |
| 99 | + |
| 100 | +```cpp |
| 101 | +#include <ranges> |
| 102 | + |
| 103 | +class Solution { |
| 104 | +public: |
| 105 | + bool phonePrefix(vector<string>& numbers) { |
| 106 | + ranges::sort(numbers, [](const string& a, const string& b) { |
| 107 | + return a.size() < b.size(); |
| 108 | + }); |
| 109 | + for (int i = 0; i < numbers.size(); i++) { |
| 110 | + if (ranges::any_of(numbers | views::take(i), [&](const string& t) { |
| 111 | + return numbers[i].starts_with(t); |
| 112 | + })) { |
| 113 | + return false; |
| 114 | + } |
| 115 | + } |
| 116 | + return true; |
| 117 | + } |
| 118 | +}; |
| 119 | +``` |
| 120 | +
|
| 121 | +#### Go |
| 122 | +
|
| 123 | +```go |
| 124 | +func phonePrefix(numbers []string) bool { |
| 125 | + sort.Slice(numbers, func(i, j int) bool { |
| 126 | + return len(numbers[i]) < len(numbers[j]) |
| 127 | + }) |
| 128 | + for i, s := range numbers { |
| 129 | + for _, t := range numbers[:i] { |
| 130 | + if strings.HasPrefix(s, t) { |
| 131 | + return false |
| 132 | + } |
| 133 | + } |
| 134 | + } |
| 135 | + return true |
| 136 | +} |
| 137 | +``` |
| 138 | + |
| 139 | +#### TypeScript |
| 140 | + |
| 141 | +```ts |
| 142 | +function phonePrefix(numbers: string[]): boolean { |
| 143 | + numbers.sort((a, b) => a.length - b.length); |
| 144 | + for (let i = 0; i < numbers.length; i++) { |
| 145 | + for (let j = 0; j < i; j++) { |
| 146 | + if (numbers[i].startsWith(numbers[j])) { |
| 147 | + return false; |
| 148 | + } |
| 149 | + } |
| 150 | + } |
| 151 | + return true; |
| 152 | +} |
| 153 | +``` |
| 154 | + |
| 155 | +<!-- tabs:end --> |
| 156 | + |
| 157 | +<!-- solution:end --> |
| 158 | + |
| 159 | +<!-- problem:end --> |
0 commit comments