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:
+
+
+ - Contains numbers greater than
255
in any octet
+ - Has leading zeros in any octet (like
01.02.03.04
)
+ - Has less or more than
4
octets
+
+
+Return the result table ordered by invalid_count
, ip
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:
+
+
+ - 256.1.2.3 is invalid because 256 > 255
+ - 192.168.001.1 is invalid because of leading zeros
+ - 192.168.1 is invalid because it has only 3 octets
+
+
+
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:
+
+
+ - Contains numbers greater than
255
in any octet
+ - Has leading zeros in any octet (like
01.02.03.04
)
+ - Has less or more than
4
octets
+
+
+Return the result table ordered by invalid_count
, ip
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:
+
+
+ - 256.1.2.3 is invalid because 256 > 255
+ - 192.168.001.1 is invalid because of leading zeros
+ - 192.168.1 is invalid because it has only 3 octets
+
+
+
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