LeetCode - #180 Swift 实现连续数字查询


文章目录

摘要

本文将解决如何从日志数据中找出连续出现至少三次的数字。通过 SQL 查询语句结合 Swift 数据库操作,我们将完成这一任务。文章提供问题描述、Swift 题解答案、代码分析、测试案例和复杂度分析,并附带完整的可运行代码模块。

描述

SQL Schema / Pandas Schema

表:Logs

txt 复制代码
+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| num         | varchar |
+-------------+---------+
在 SQL 中,id 是该表的主键。
id 是一个自增列。

找出所有至少连续出现三次的数字。

返回的结果表中的数据可以按 任意顺序 排列。

结果格式如下面的例子所示:

示例 1:

txt 复制代码
输入:
Logs 表:
+----+-----+
| id | num |
+----+-----+
| 1  | 1   |
| 2  | 1   |
| 3  | 1   |
| 4  | 2   |
| 5  | 1   |
| 6  | 2   |
| 7  | 2   |
+----+-----+
输出:
Result 表:
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1               |
+-----------------+
解释: 1 是唯一连续出现至少三次的数字。

SQL 解法

为了找出至少连续出现三次的数字,我们可以使用 SQL 的窗口函数 LEADLAG

sql 复制代码
SELECT DISTINCT num AS ConsecutiveNums
FROM (
    SELECT 
        num,
        LAG(num) OVER (ORDER BY id) AS prev_num,
        LEAD(num) OVER (ORDER BY id) AS next_num
    FROM Logs
) AS temp
WHERE num = prev_num AND num = next_num;

说明:

  1. 使用 LAGLEAD 获取当前行的前一行和后一行的数字。
  2. 检查当前数字 num 是否与前后两个数字相同。
  3. 使用 DISTINCT 去重以确保每个符合条件的数字只出现一次。

Swift 题解代码

以下是基于 Swift 的完整实现代码:

swift 复制代码
import SQLite3

func findConsecutiveNumbers(databasePath: String) -> [String] {
    var db: OpaquePointer?
    var stmt: OpaquePointer?
    var results: [String] = []

    // 打开数据库连接
    if sqlite3_open(databasePath, &db) == SQLITE_OK {
        let query = """
        SELECT DISTINCT num AS ConsecutiveNums
        FROM (
            SELECT 
                num,
                LAG(num) OVER (ORDER BY id) AS prev_num,
                LEAD(num) OVER (ORDER BY id) AS next_num
            FROM Logs
        ) AS temp
        WHERE num = prev_num AND num = next_num;
        """
        
        // 准备查询语句
        if sqlite3_prepare_v2(db, query, -1, &stmt, nil) == SQLITE_OK {
            // 执行查询并获取结果
            while sqlite3_step(stmt) == SQLITE_ROW {
                if let cString = sqlite3_column_text(stmt, 0) {
                    let num = String(cString: cString)
                    results.append(num)
                }
            }
        } else {
            print("SQL Error: \(String(cString: sqlite3_errmsg(db)))")
        }
        
        // 清理资源
        sqlite3_finalize(stmt)
    }
    sqlite3_close(db)

    return results
}

// 示例测试
let databasePath = "path_to_your_database.sqlite"
let consecutiveNumbers = findConsecutiveNumbers(databasePath: databasePath)
print("Consecutive Numbers: \(consecutiveNumbers)")

Swift 题解代码分析

核心逻辑

  1. SQL 查询:

    • 使用 LAGLEAD 分别获取当前行的前一行和后一行数字。
    • 通过检查条件 num = prev_num AND num = next_num 找到符合条件的数字。
    • DISTINCT 去重,保证每个数字仅出现在结果中一次。
  2. Swift 数据库接口:

    • 通过 sqlite3 API 连接 SQLite 数据库。
    • 执行查询语句并遍历结果集,将符合条件的数字存储到数组中。
  3. 输出结果:

    • 将查询结果以数组形式返回,供后续处理。

关键函数

  • sqlite3_open: 打开数据库连接。
  • sqlite3_prepare_v2: 准备 SQL 查询语句。
  • sqlite3_step: 执行查询语句并逐行读取结果。
  • sqlite3_finalizesqlite3_close: 清理资源并关闭数据库。

示例测试及结果

测试 1

数据库内容:

txt 复制代码
+----+-----+
| id | num |
+----+-----+
| 1  | 1   |
| 2  | 1   |
| 3  | 1   |
| 4  | 2   |
| 5  | 1   |
| 6  | 2   |
| 7  | 2   |
+----+-----+

运行结果:

txt 复制代码
Consecutive Numbers: ["1"]

测试 2

数据库内容:

txt 复制代码
+----+-----+
| id | num |
+----+-----+
| 1  | 3   |
| 2  | 3   |
| 3  | 3   |
| 4  | 4   |
| 5  | 4   |
| 6  | 4   |
| 7  | 5   |
+----+-----+

运行结果:

txt 复制代码
Consecutive Numbers: ["3", "4"]

时间复杂度

  1. SQL 查询:
    • 遍历 Logs 表一次以获取窗口函数结果,复杂度为 (O(n))。
    • 对结果表进行过滤,复杂度为 (O(n))。

总时间复杂度: (O(n))

空间复杂度

  1. SQL 查询:
    • 使用临时表存储窗口函数结果,空间复杂度为 (O(n))。
  2. Swift 数组:
    • 存储查询结果的数组,空间复杂度为 (O(k)),其中 (k) 是结果集中符合条件的数字个数。

总空间复杂度: (O(n))

总结

通过使用窗口函数 LAGLEAD,我们能够高效地解决连续出现数字的查询问题。本解决方案不仅适用于 SQL 查询,还能通过 Swift 集成到实际项目中,为日志分析、数据挖掘等场景提供可靠支持。

相关推荐
狄加山6754 小时前
数据结构(查找算法)
数据结构·数据库·算法
陌然。。5 小时前
【701. 二叉搜索树中的插入操作 中等】
数据结构·c++·算法·leetcode·深度优先
Ritsu栗子5 小时前
代码随想录算法训练营day25
c++·算法
是十一月末5 小时前
机器学习之过采样和下采样调整不均衡样本的逻辑回归模型
人工智能·python·算法·机器学习·逻辑回归
生信碱移5 小时前
万字长文:机器学习的数学基础(易读)
大数据·人工智能·深度学习·线性代数·算法·数学建模·数据分析
疯狂小料5 小时前
Python3刷算法来呀,贪心系列题单
开发语言·python·算法
Cosmoshhhyyy5 小时前
LeetCode:2274. 不含特殊楼层的最大连续楼层数(排序 Java)
java·算法·leetcode
KeyPan5 小时前
【机器学习:四、多输入变量的回归问题】
人工智能·数码相机·算法·机器学习·计算机视觉·数据挖掘·回归
码力全開5 小时前
C 语言奇幻之旅 - 第14篇:C 语言高级主题
服务器·c语言·开发语言·人工智能·算法