当前位置: 首页 > news >正文

LeetCode 第 262 题全解析:从 SQL 到 Swift 的数据分析实战

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案(SQL)
    • Swift 题解代码分析
    • 代码示例(可运行 Demo)
    • 示例测试及结果
    • 时间复杂度分析
    • 空间复杂度分析
    • 总结
    • 未来展望

摘要

在实际业务中,打车平台要监控行程的取消率,及时识别服务质量的问题。这篇文章围绕 LeetCode 第 262 题,带大家用 Swift 和 SQL 解题,并深入聊聊如何结合用户数据和行程数据去计算每天的取消率,尤其是只计算“非禁止用户”的数据。咱们还会补充一个可运行的 Swift Demo 来模拟分析过程,并讲解这类题目在数据分析、风控和运营决策中的价值。

描述

这个题目其实就是想让我们统计每天的“非被封禁用户”的取消率。用户数据在一张表里,行程数据在另一张表里。我们要结合这两张表筛选出符合条件的数据:

  • 时间在 2013-10-01 到 2013-10-03 之间

  • 用户不能是被禁用的(banned = No

  • 最终结果要按照天维度输出,每天的取消率保留两位小数

而且要注意,只有司机和乘客都不是禁止用户的行程才参与计算。

题解答案(SQL)

虽然你要的是 Swift 题解,但这道题核心在于 SQL 联表计算,我们先看 SQL 部分:

SELECT request_at AS Day,ROUND(SUM(CASE WHEN status IN ('cancelled_by_driver', 'cancelled_by_client') THEN 1ELSE 0END) * 1.0 / COUNT(*), 2) AS "Cancellation Rate"
FROM Trips t
JOIN Users c ON t.client_id = c.users_id AND c.banned = 'No'
JOIN Users d ON t.driver_id = d.users_id AND d.banned = 'No'
WHERE request_at BETWEEN '2013-10-01' AND '2013-10-03'
GROUP BY request_at;

Swift 题解代码分析

我们用 Swift 来模拟整个 SQL 的流程。假设我们有两个 JSON 数据源,分别对应 Trips 表和 Users 表,我们会:

  1. 解析数据结构

  2. 过滤掉被封禁的用户

  3. 筛选出符合时间条件的行程

  4. 分天统计总行程数和取消的行程数

  5. 最终计算每天的取消率并打印结果

代码示例(可运行 Demo)

import Foundationstruct Trip {let id: Intlet clientId: Intlet driverId: Intlet status: Stringlet requestAt: String
}struct User {let userId: Intlet banned: Stringlet role: String
}let users: [User] = [.init(userId: 1, banned: "No", role: "client"),.init(userId: 2, banned: "Yes", role: "client"),.init(userId: 3, banned: "No", role: "client"),.init(userId: 4, banned: "No", role: "client"),.init(userId: 10, banned: "No", role: "driver"),.init(userId: 11, banned: "No", role: "driver"),.init(userId: 12, banned: "No", role: "driver"),.init(userId: 13, banned: "No", role: "driver")
]let trips: [Trip] = [.init(id: 1, clientId: 1, driverId: 10, status: "completed", requestAt: "2013-10-01"),.init(id: 2, clientId: 2, driverId: 11, status: "cancelled_by_driver", requestAt: "2013-10-01"),.init(id: 3, clientId: 3, driverId: 12, status: "completed", requestAt: "2013-10-01"),.init(id: 4, clientId: 4, driverId: 13, status: "cancelled_by_client", requestAt: "2013-10-01"),.init(id: 5, clientId: 1, driverId: 10, status: "completed", requestAt: "2013-10-02"),.init(id: 6, clientId: 2, driverId: 11, status: "completed", requestAt: "2013-10-02"),.init(id: 7, clientId: 3, driverId: 12, status: "completed", requestAt: "2013-10-02"),.init(id: 8, clientId: 2, driverId: 12, status: "completed", requestAt: "2013-10-03"),.init(id: 9, clientId: 3, driverId: 10, status: "completed", requestAt: "2013-10-03"),.init(id: 10, clientId: 4, driverId: 13, status: "cancelled_by_driver", requestAt: "2013-10-03")
]let bannedUsers = Set(users.filter { $0.banned == "Yes" }.map { $0.userId })var result: [String: (cancelled: Int, total: Int)] = [:]for trip in trips {guard !bannedUsers.contains(trip.clientId),!bannedUsers.contains(trip.driverId),["2013-10-01", "2013-10-02", "2013-10-03"].contains(trip.requestAt)else { continue }let date = trip.requestAtvar entry = result[date] ?? (0, 0)if trip.status == "cancelled_by_driver" || trip.status == "cancelled_by_client" {entry.cancelled += 1}entry.total += 1result[date] = entry
}for (day, entry) in result {let rate = entry.total == 0 ? 0.0 : Double(entry.cancelled) / Double(entry.total)print("\(day): \(String(format: "%.2f", rate))")
}

示例测试及结果

运行上述 Swift 程序,将会输出:

2013-10-01: 0.33
2013-10-02: 0.00
2013-10-03: 0.50

这与题目给出的标准结果一致。

时间复杂度分析

假设行程数为 n,用户数为 m

  • 筛选禁止用户集合:O(m)

  • 遍历 trips 数据:O(n)

  • 最终输出:O(k),其中 k 是天数,这里固定为 3 天

总体时间复杂度是:O(n + m)

空间复杂度分析

  • 存储禁止用户集合:O(m)

  • 结果字典 result:最多三天,常量空间

所以总空间复杂度是:O(m)

总结

这题表面是 SQL 题,其实是在考察我们对数据的过滤和聚合能力。无论是用 SQL 写联表查询,还是用 Swift 做数据模拟,都离不开一个核心思想——干净准确的数据处理。

这个例子在实际项目中特别常见,比如:

  • 运营要知道每天的取消率趋势

  • 数据平台需要过滤掉异常数据(比如封禁用户)

  • 数据分析师希望看到更精准的业务 KPI

未来展望

这类数据处理可以推广到更多场景,比如:

  • 留存率、点击率、完成率的计算

  • 实时监控系统中的数据聚合

  • 用户行为数据的质量控制

未来我们可以拓展这个 Demo,接入真实数据库或 API 数据源,构建一个完整的监控看板。

相关文章:

  • 正向代理和反向代理
  • 【VS Code】打开远程服务器Docker项目或文件夹
  • FramePack V2版 - 支持首尾帧生成,支持LoRA,支持批量,支持50系显卡,一个强大的AI视频生成软件 本地一键整合包下载
  • 一款强大的实时协作Markdown工具 | CodiMD 9.6K ⭐
  • 小小矩阵设计
  • C++学习之类与对象
  • 一款丰富的工作流自动化平台 | N8N 83.6K ⭐
  • C++23 中 static_assert 和 if constexpr 的窄化布尔转换
  • 【锂电池剩余寿命预测】BiLSTM双向长短期记忆神经网络锂电池剩余寿命预测(Matlab源码)
  • Python基于语音识别的智能垃圾分类系统【附源码、文档说明】
  • 前端之勇闯DOM关
  • Nginx常用命令,及常见错误
  • PR网表出现assign该如何解决
  • 音视频小白系统入门课-3
  • 第十五讲、Isaaclab中在机器人上添加传感器
  • # 利用迁移学习优化食物分类模型:基于ResNet18的实践
  • 【Java面试笔记:基础】6.动态代理是基于什么原理?
  • pip的源管理和包管理
  • 黑马点评之Feed流技术实现关注推送与滚动分页查询
  • 光谱相机在肤质检测中的应用
  • 央媒关注脑瘫女骑手:7年跑出7.3万多份单,努力撑起生活
  • 小鹏机器人IRON亮相上海车展,何小鹏:相信更多人形机器人会现身车展
  • 郑庆华任同济大学党委书记
  • 广东江门公布“小客车坠海致3死”事故评估报告,司机被判三年缓五年
  • 工程院院士应汉杰不再担任苏州大学校长
  • 威廉·透纳诞辰250周年|他是现代艺术之父