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

字节面试手撕题:版本号排序

题目

给定版本号:version = ["1.5.1", "1.45.0", "1.99.99", "3.3.3.3", "1.5", "6"]

写一个函数对版本号从小到大排序。

解答

为了对版本号进行排序,我们需要将每个版本号字符串转换为整数元组,然后根据这些元组进行排序。这样可以确保每个部分按数值大小正确比较,并处理不同长度的版本号:

  1. 分割和转换:将每个版本号字符串按点号分割成多个部分,并将每个部分转换为整数。

  2. 元组比较:利用Python元组的自然排序机制,逐个比较每个部分的值。较短版本号在比较时,缺失的部分视为0。

  3. 排序:使用Python的内置排序函数,根据转换后的元组进行排序。

def sort_versions(versions):return sorted(versions, key=lambda v: tuple(map(int, v.split('.'))))# 示例测试
version = ["1.5.1", "1.45.0", "1.99.99", "3.3.3.3", "1.5", "6"]
sorted_versions = sort_versions(version)
print(sorted_versions)
# ['1.5', '1.5.1', '1.45.0', '1.99.99', '3.3.3.3', '6']

附1:key=lambda v: tuple(map(int, v.split('.')))的解释

1.v.split('.')

  • 作用:将版本号字符串按点号.分割成多个部分
  • 结果:生成字符串列表(每个部分仍是字符串)
"1.5.1".split('.')  # 返回: ['1', '5', '1']
"3.3.3.3".split('.')  # 返回: ['3', '3', '3', '3']
"6".split('.')  # 返回: ['6']

2.map(int, ...)

  • 作用:将每个字符串部分转换为整数

  • 为什么需要:避免字符串比较(如 "10" < "2" 的错误情况)

map(int, ['1', '5', '1'])  # 转换为: [1, 5, 1]
map(int, ['3', '3', '3', '3'])  # 转换为: [3, 3, 3, 3]
map(int, ['6'])  # 转换为: [6]

3.tuple(...)

  • 作用:将整数列表转换为元组

  • 为什么需要:元组支持按元素顺序比较(这是版本号排序的关键)

tuple([1, 5, 1])  # 转换为: (1, 5, 1)
tuple([3, 3, 3, 3])  # 转换为: (3, 3, 3, 3)
tuple([6])  # 转换为: (6,)

4.lambda v: ...

  • 作用:创建一个临时函数,接受版本号字符串v,返回转换后的元组

# 定义一个匿名函数
lambda v: tuple(map(int, v.split('.')))

相当于:

def key_function(v):parts = v.split('.')int_parts = [int(part) for part in parts]return tuple(int_parts)

附2:快速排序的代码实现(递归算法)

快速排序是一种高效的排序算法,采用分治策略。其基本思想是选择一个基准元素,将数组分为两部分:小于基准的部分和大于基准的部分,然后递归地对这两部分进行排序。

  1. 基准选择

    • 选择数组中间元素作为基准(pivot = arr[len(arr) // 2]

    • 也可以选择第一个、最后一个或随机元素作为基准

  2. 分区操作

    • left:存储所有小于基准的元素

    • middle:存储所有等于基准的元素(处理重复值)

    • right:存储所有大于基准的元素

  3. 递归排序

    • 对左右分区递归调用快速排序

    • 将排序后的左分区、中间元素、右分区合并

  4. 时间复杂度:

    • 平均情况:O(n log n)

    • 最坏情况(已排序数组):O(n²) - 可通过随机选择基准避免

    • 空间复杂度:O(log n)(递归调用栈)

def quick_sort(arr):"""快速排序函数:param arr: 待排序列表:return: 排序后的列表"""# 递归终止条件:当数组长度为0或1时,直接返回if len(arr) <= 1:return arr# 选择基准元素(这里选择中间元素)pivot = arr[len(arr) // 2]# 创建三个分区left = [x for x in arr if x < pivot]    # 小于基准的元素middle = [x for x in arr if x == pivot]  # 等于基准的元素right = [x for x in arr if x > pivot]   # 大于基准的元素# 递归排序左右分区,并合并结果return quick_sort(left) + middle + quick_sort(right)# 测试示例
if __name__ == "__main__":test_arr = [3, 6, 8, 10, 1, 2, 1]print("原始数组:", test_arr)sorted_arr = quick_sort(test_arr)print("排序结果:", sorted_arr)

附3:快速排序的代码实现(非递归算法)

快速排序的非递归实现使用栈来模拟递归过程,避免了递归调用的系统栈开销。下面是完整的实现:

def quick_sort_non_recursive(arr):"""快速排序的非递归实现:param arr: 待排序列表:return: 排序后的列表(原地排序)"""if len(arr) <= 1:return arr# 使用栈存储待处理的子数组范围stack = []# 初始范围:整个数组stack.append((0, len(arr) - 1))while stack:# 获取当前处理的子数组范围low, high = stack.pop()# 如果子数组长度小于等于1,跳过if low >= high:continue# 分区操作pivot_index = partition(arr, low, high)# 将左右子数组范围压入栈中# 先压入较大的子数组,后压入较小的子数组(优化栈深度)if (pivot_index - low) > (high - pivot_index):stack.append((low, pivot_index - 1))stack.append((pivot_index + 1, high))else:stack.append((pivot_index + 1, high))stack.append((low, pivot_index - 1))return arrdef partition(arr, low, high):"""分区函数:选择基准元素并将数组分为两部分:param arr: 待分区数组:param low: 子数组起始索引:param high: 子数组结束索引:return: 基准元素的最终位置"""# 选择基准元素(这里使用三数取中法优化)mid = low + (high - low) // 2# 对左、中、右三个元素进行排序if arr[low] > arr[mid]:arr[low], arr[mid] = arr[mid], arr[low]if arr[low] > arr[high]:arr[low], arr[high] = arr[high], arr[low]if arr[mid] > arr[high]:arr[mid], arr[high] = arr[high], arr[mid]# 选择中位数作为基准(放在high-1位置)pivot = arr[mid]arr[mid], arr[high] = arr[high], arr[mid]# 分区指针i = low - 1# 遍历子数组for j in range(low, high):if arr[j] <= pivot:i += 1arr[i], arr[j] = arr[j], arr[i]# 将基准元素放到正确位置arr[i + 1], arr[high] = arr[high], arr[i + 1]return i + 1# 测试代码
if __name__ == "__main__":# 测试用例test_cases = [[3, 6, 8, 10, 1, 2, 1],[10, 7, 8, 9, 1, 5],[],[1],[5, 4, 3, 2, 1],[1, 2, 3, 4, 5],[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]]for arr in test_cases:print(f"原始数组: {arr}")sorted_arr = quick_sort_non_recursive(arr.copy())print(f"排序结果: {sorted_arr}")print()'''
原始数组: [3, 6, 8, 10, 1, 2, 1]
排序结果: [1, 1, 2, 3, 6, 8, 10]原始数组: [10, 7, 8, 9, 1, 5]
排序结果: [1, 5, 7, 8, 9, 10]原始数组: []
排序结果: []原始数组: [1]
排序结果: [1]原始数组: [5, 4, 3, 2, 1]
排序结果: [1, 2, 3, 4, 5]原始数组: [1, 2, 3, 4, 5]
排序结果: [1, 2, 3, 4, 5]原始数组: [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
排序结果: [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
'''

相关文章:

  • MyBatis03——SpringBoot整合MyBatis
  • OpenLayers 地图标注之图文标注
  • C#数字图像处理(二)
  • Ⅰ.计算机二级选择题(C语言概述)
  • 【第16届蓝桥杯 | 软件赛】CB组省赛第二场
  • [蓝桥杯]外卖店优先级
  • 串口通信技术及USART应用研究
  • 鸿蒙仓颉语言开发教程:自定义弹窗
  • 开始通信之旅-----话题通信
  • python 将音乐和人声分离
  • 如何编写GitLab-CI配置文件
  • 链表题解——合并两个有序链表【LeetCode】
  • 【数据结构】顺序表和链表详解(上)
  • 剪枝中的 `break` 与 `return` 区别详解
  • JS中的函数防抖和节流:提升性能的关键技术
  • barker-OFDM模糊函数原理及仿真
  • DelphiXe12创建DataSnap REST Application
  • 阴盘奇门 api数据接口
  • 中国高分辨率高质量地面NO2数据集(2008-2023)
  • ​​技术深度解析:《鸿蒙5.0+:无感续航的智能魔法》​
  • 武汉市网站建设/全国免费发布信息平台
  • 程序员帮人做黑彩网站/seo软件工具
  • 简单网页设计模板网站/qq推广链接生成
  • 简约好看的网站/互联网营销推广怎么做
  • 官方模板/seo网站优化论文
  • 武汉网页电商设计培训/西安自动seo