diff --git a/.prettierignore b/.prettierignore index 13715bc116db8..47b55e9bdf606 100644 --- a/.prettierignore +++ b/.prettierignore @@ -26,3 +26,4 @@ node_modules/ /solution/3100-3199/3150.Invalid Tweets II/Solution.sql /solution/3100-3199/3198.Find Cities in Each State/Solution.sql /solution/3300-3399/3328.Find Cities in Each State II/Solution.sql +/solution/3400-3499/3451.Find Invalid IP Addresses/Solution.sql diff --git a/solution/3400-3499/3451.Find Invalid IP Addresses/README.md b/solution/3400-3499/3451.Find Invalid IP Addresses/README.md new file mode 100644 index 0000000000000..c09c41e732002 --- /dev/null +++ b/solution/3400-3499/3451.Find Invalid IP Addresses/README.md @@ -0,0 +1,162 @@ +--- +comments: true +difficulty: 困难 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README.md +tags: + - 数据库 +--- + + + +# [3451. Find Invalid IP Addresses](https://leetcode.cn/problems/find-invalid-ip-addresses) + +[English Version](/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README_EN.md) + +## 题目描述 + + + +

Table: logs

+ +
++-------------+---------+
+| Column Name | Type    |
++-------------+---------+
+| log_id      | int     |
+| ip          | varchar |
+| status_code | int     |
++-------------+---------+
+log_id is the unique key for this table.
+Each row contains server access log information including IP address and HTTP status code.
+
+ +

Write a solution to find invalid IP addresses. An IPv4 address is invalid if it meets any of these conditions:

+ + + +

Return the result table ordered by invalid_countip in descending order respectively

+ +

The result format is in the following example.

+ +

 

+

Example:

+ +
+

Input:

+ +

logs table:

+ +
++--------+---------------+-------------+
+| log_id | ip            | status_code |
++--------+---------------+-------------+
+| 1      | 192.168.1.1   | 200         |
+| 2      | 256.1.2.3     | 404         |
+| 3      | 192.168.001.1 | 200         |
+| 4      | 192.168.1.1   | 200         |
+| 5      | 192.168.1     | 500         |
+| 6      | 256.1.2.3     | 404         |
+| 7      | 192.168.001.1 | 200         |
++--------+---------------+-------------+
+
+ +

Output:

+ +
++---------------+--------------+
+| ip            | invalid_count|
++---------------+--------------+
+| 256.1.2.3     | 2            |
+| 192.168.001.1 | 2            |
+| 192.168.1     | 1            |
++---------------+--------------+
+
+ +

Explanation:

+ + + +

The output table is ordered by invalid_count, ip in descending order respectively.

+
+ + + +## 解法 + + + +### 方法一:模拟 + +我们可以根据题意,判断 IP 地址是否不合法,判断的条件有: + +1. IP 地址中的 `.` 的个数不等于 $3$; +2. IP 地址中的某个 octet 以 `0` 开头; +3. IP 地址中的某个 octet 大于 $255$。 + +然后我们将不合法的 IP 地址进行分组,并统计每个不合法的 IP 地址的个数 `invalid_count`,最后按照 `invalid_count` 和 `ip` 降序排序。 + + + +#### MySQL + +```sql +SELECT + ip, + COUNT(*) AS invalid_count +FROM logs +WHERE + LENGTH(ip) - LENGTH(REPLACE(ip, '.', '')) != 3 + OR SUBSTRING_INDEX(ip, '.', 1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(ip, '.', -1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(ip, '.', 1) > 255 + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1) > 255 + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1) > 255 + OR SUBSTRING_INDEX(ip, '.', -1) > 255 +GROUP BY 1 +ORDER BY 2 DESC, 1 DESC; +``` + +#### Pandas + +```python +import pandas as pd + + +def find_invalid_ips(logs: pd.DataFrame) -> pd.DataFrame: + def is_valid_ip(ip: str) -> bool: + octets = ip.split(".") + if len(octets) != 4: + return False + for octet in octets: + if not octet.isdigit(): + return False + value = int(octet) + if not 0 <= value <= 255 or octet != str(value): + return False + return True + + logs["is_valid"] = logs["ip"].apply(is_valid_ip) + invalid_ips = logs[~logs["is_valid"]] + invalid_count = invalid_ips["ip"].value_counts().reset_index() + invalid_count.columns = ["ip", "invalid_count"] + result = invalid_count.sort_values( + by=["invalid_count", "ip"], ascending=[False, False] + ) + return result +``` + + + + + + diff --git a/solution/3400-3499/3451.Find Invalid IP Addresses/README_EN.md b/solution/3400-3499/3451.Find Invalid IP Addresses/README_EN.md new file mode 100644 index 0000000000000..354279f8570c3 --- /dev/null +++ b/solution/3400-3499/3451.Find Invalid IP Addresses/README_EN.md @@ -0,0 +1,162 @@ +--- +comments: true +difficulty: Hard +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README_EN.md +tags: + - Database +--- + + + +# [3451. Find Invalid IP Addresses](https://leetcode.com/problems/find-invalid-ip-addresses) + +[中文文档](/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README.md) + +## Description + + + +

Table: logs

+ +
++-------------+---------+
+| Column Name | Type    |
++-------------+---------+
+| log_id      | int     |
+| ip          | varchar |
+| status_code | int     |
++-------------+---------+
+log_id is the unique key for this table.
+Each row contains server access log information including IP address and HTTP status code.
+
+ +

Write a solution to find invalid IP addresses. An IPv4 address is invalid if it meets any of these conditions:

+ + + +

Return the result table ordered by invalid_countip in descending order respectively

+ +

The result format is in the following example.

+ +

 

+

Example:

+ +
+

Input:

+ +

logs table:

+ +
++--------+---------------+-------------+
+| log_id | ip            | status_code |
++--------+---------------+-------------+
+| 1      | 192.168.1.1   | 200         |
+| 2      | 256.1.2.3     | 404         |
+| 3      | 192.168.001.1 | 200         |
+| 4      | 192.168.1.1   | 200         |
+| 5      | 192.168.1     | 500         |
+| 6      | 256.1.2.3     | 404         |
+| 7      | 192.168.001.1 | 200         |
++--------+---------------+-------------+
+
+ +

Output:

+ +
++---------------+--------------+
+| ip            | invalid_count|
++---------------+--------------+
+| 256.1.2.3     | 2            |
+| 192.168.001.1 | 2            |
+| 192.168.1     | 1            |
++---------------+--------------+
+
+ +

Explanation:

+ + + +

The output table is ordered by invalid_count, ip in descending order respectively.

+
+ + + +## Solutions + + + +### Solution 1: Simulation + +We can determine if an IP address is invalid based on the following conditions: + +1. The number of `.` in the IP address is not equal to $3$; +2. Any octet in the IP address starts with `0`; +3. Any octet in the IP address is greater than $255$. + +Then we group the invalid IP addresses and count the occurrences of each invalid IP address `invalid_count`, and finally sort by `invalid_count` and `ip` in descending order. + + + +#### MySQL + +```sql +SELECT + ip, + COUNT(*) AS invalid_count +FROM logs +WHERE + LENGTH(ip) - LENGTH(REPLACE(ip, '.', '')) != 3 + OR SUBSTRING_INDEX(ip, '.', 1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(ip, '.', -1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(ip, '.', 1) > 255 + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1) > 255 + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1) > 255 + OR SUBSTRING_INDEX(ip, '.', -1) > 255 +GROUP BY 1 +ORDER BY 2 DESC, 1 DESC; +``` + +#### Pandas + +```python +import pandas as pd + + +def find_invalid_ips(logs: pd.DataFrame) -> pd.DataFrame: + def is_valid_ip(ip: str) -> bool: + octets = ip.split(".") + if len(octets) != 4: + return False + for octet in octets: + if not octet.isdigit(): + return False + value = int(octet) + if not 0 <= value <= 255 or octet != str(value): + return False + return True + + logs["is_valid"] = logs["ip"].apply(is_valid_ip) + invalid_ips = logs[~logs["is_valid"]] + invalid_count = invalid_ips["ip"].value_counts().reset_index() + invalid_count.columns = ["ip", "invalid_count"] + result = invalid_count.sort_values( + by=["invalid_count", "ip"], ascending=[False, False] + ) + return result +``` + + + + + + diff --git a/solution/3400-3499/3451.Find Invalid IP Addresses/Solution.py b/solution/3400-3499/3451.Find Invalid IP Addresses/Solution.py new file mode 100644 index 0000000000000..e42b6e3f70e56 --- /dev/null +++ b/solution/3400-3499/3451.Find Invalid IP Addresses/Solution.py @@ -0,0 +1,24 @@ +import pandas as pd + + +def find_invalid_ips(logs: pd.DataFrame) -> pd.DataFrame: + def is_valid_ip(ip: str) -> bool: + octets = ip.split(".") + if len(octets) != 4: + return False + for octet in octets: + if not octet.isdigit(): + return False + value = int(octet) + if not 0 <= value <= 255 or octet != str(value): + return False + return True + + logs["is_valid"] = logs["ip"].apply(is_valid_ip) + invalid_ips = logs[~logs["is_valid"]] + invalid_count = invalid_ips["ip"].value_counts().reset_index() + invalid_count.columns = ["ip", "invalid_count"] + result = invalid_count.sort_values( + by=["invalid_count", "ip"], ascending=[False, False] + ) + return result diff --git a/solution/3400-3499/3451.Find Invalid IP Addresses/Solution.sql b/solution/3400-3499/3451.Find Invalid IP Addresses/Solution.sql new file mode 100644 index 0000000000000..bc805b2627642 --- /dev/null +++ b/solution/3400-3499/3451.Find Invalid IP Addresses/Solution.sql @@ -0,0 +1,19 @@ +SELECT + ip, + COUNT(*) AS invalid_count +FROM logs +WHERE + LENGTH(ip) - LENGTH(REPLACE(ip, '.', '')) != 3 + + OR SUBSTRING_INDEX(ip, '.', 1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1) REGEXP '^0[0-9]' + OR SUBSTRING_INDEX(ip, '.', -1) REGEXP '^0[0-9]' + + OR SUBSTRING_INDEX(ip, '.', 1) > 255 + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1) > 255 + OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1) > 255 + OR SUBSTRING_INDEX(ip, '.', -1) > 255 + +GROUP BY 1 +ORDER BY 2 DESC, 1 DESC; diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index a0b774b80f5b0..511eed53830c1 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -309,6 +309,7 @@ | 3415 | [查找具有三个连续数字的产品](/solution/3400-3499/3415.Find%20Products%20with%20Three%20Consecutive%20Digits/README.md) | `数据库` | 简单 | 🔒 | | 3421 | [查找进步的学生](/solution/3400-3499/3421.Find%20Students%20Who%20Improved/README.md) | `数据库` | 中等 | | | 3436 | [查找合法邮箱](/solution/3400-3499/3436.Find%20Valid%20Emails/README.md) | `数据库` | 简单 | | +| 3451 | [Find Invalid IP Addresses](/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README.md) | | 困难 | | ## 版权 diff --git a/solution/DATABASE_README_EN.md b/solution/DATABASE_README_EN.md index bddcbccb696cd..77a7de88cae67 100644 --- a/solution/DATABASE_README_EN.md +++ b/solution/DATABASE_README_EN.md @@ -307,6 +307,7 @@ Press Control + F(or Command + F on | 3415 | [Find Products with Three Consecutive Digits](/solution/3400-3499/3415.Find%20Products%20with%20Three%20Consecutive%20Digits/README_EN.md) | `Database` | Easy | 🔒 | | 3421 | [Find Students Who Improved](/solution/3400-3499/3421.Find%20Students%20Who%20Improved/README_EN.md) | `Database` | Medium | | | 3436 | [Find Valid Emails](/solution/3400-3499/3436.Find%20Valid%20Emails/README_EN.md) | `Database` | Easy | | +| 3451 | [Find Invalid IP Addresses](/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README_EN.md) | | Hard | | ## Copyright diff --git a/solution/README.md b/solution/README.md index e72fac6f5073b..2ddadf109c1da 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3461,6 +3461,7 @@ | 3448 | [统计可以被最后一个数位整除的子字符串数目](/solution/3400-3499/3448.Count%20Substrings%20Divisible%20By%20Last%20Digit/README.md) | | 困难 | 第 436 场周赛 | | 3449 | [最大化游戏分数的最小值](/solution/3400-3499/3449.Maximize%20the%20Minimum%20Game%20Score/README.md) | | 困难 | 第 436 场周赛 | | 3450 | [一张长椅的上最多学生](/solution/3400-3499/3450.Maximum%20Students%20on%20a%20Single%20Bench/README.md) | | 简单 | 🔒 | +| 3451 | [Find Invalid IP Addresses](/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README.md) | | 困难 | | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index d9f44db234e4a..afdb9763b21e2 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3459,6 +3459,7 @@ Press Control + F(or Command + F on | 3448 | [Count Substrings Divisible By Last Digit](/solution/3400-3499/3448.Count%20Substrings%20Divisible%20By%20Last%20Digit/README_EN.md) | | Hard | Weekly Contest 436 | | 3449 | [Maximize the Minimum Game Score](/solution/3400-3499/3449.Maximize%20the%20Minimum%20Game%20Score/README_EN.md) | | Hard | Weekly Contest 436 | | 3450 | [Maximum Students on a Single Bench](/solution/3400-3499/3450.Maximum%20Students%20on%20a%20Single%20Bench/README_EN.md) | | Easy | 🔒 | +| 3451 | [Find Invalid IP Addresses](/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README_EN.md) | | Hard | | ## Copyright