📜  门| GATE-CS-2015(套装3)|第 55 题(1)

📅  最后修改于: 2023-12-03 15:12:42.829000             🧑  作者: Mango

题目介绍

本题是 GATE-CS-2015(套装3)第 55 题。该题为一道算法题,需要实现一个函数。

题目描述

给定一个字符串列表 lst,请实现 suffix_sort 函数,使得该函数可以根据字符串的后缀来对 lst 中的字符串进行排序。

函数签名
def suffix_sort(lst: List[str]) -> List[str]:
    pass
输入
  • lst:一个由字符串组成的列表,其中 len(lst) <= 10^5,而一份字符串的长度 |s| <= 20,000
输出
  • 排序完成的字符串列表。
代码示例
lst = ['banana', 'apple', 'orange', 'pear', 'kiwi']
res = suffix_sort(lst)
print(res)  # ['apple', 'banana', 'kiwi', 'orange', 'pear']
题目解析

本题需要对字符串按照后缀进行排序,下面给出两种算法。

算法一
  1. 计算出字符串列表中最长字符串的长度 $n$。
  2. 构造一个 $n\times len(lst)$ 的矩阵 $A$,其第 $i$ 行第 $j$ 列表示第 $j$ 个字符串的后缀从第 $i$ 个位置开始的后缀。
  3. 对矩阵 $A$ 中的每一列进行排序。
  4. 构造一个以字符串为键,以列索引为值的字典 $lookup$。
  5. 将字典 $lookup$ 中的键排序后即为最终的排序结果。
算法二

使用 Python 默认的排序函数,并自己提供一个 key 函数来实现按照后缀比较大小的功能。

具体实现参见代码。

时间复杂度
算法一

计算矩阵 $A$ 的时间复杂度为 $O\left(\sum_{i=1}^{|lst|} |s_i|\right)$。排序时间复杂度为 $O(n\times |lst|\log |lst|)$。构建字典 $lookup$ 的时间复杂度为 $O(|lst|)$。因此总共的时间复杂度为 $O\left(\sum_{i=1}^{|lst|} |s_i| + n\times |lst|\log |lst|\right)$。

算法二

排序时间复杂度为 $O(|lst|\times |s|\log |s|)$,因此总时间复杂度为 $O(|lst|\times |s|\log |s|)$。

算法实现
算法一
from typing import List


def suffix_sort(lst: List[str]) -> List[str]:
    n = max(len(s) for s in lst)
    A = [[(s[i:] + chr(0)*(n-len(s)))[:n] for i in range(len(s))] for s in lst]
    for i in range(len(lst)):
        A[i].sort()
    lookup = {A[i][j]: j for i in range(len(lst)) for j in range(len(A[i]))}
    return sorted(lst, key=lambda x: lookup[x])


lst = ['banana', 'apple', 'orange', 'pear', 'kiwi']
res = suffix_sort(lst)
print(res)  # ['apple', 'banana', 'kiwi', 'orange', 'pear']
算法二
from typing import List


def suffix_sort(lst: List[str]) -> List[str]:
    return sorted(lst, key=lambda x: x[::-1])


lst = ['banana', 'apple', 'orange', 'pear', 'kiwi']
res = suffix_sort(lst)
print(res)  # ['apple', 'banana', 'kiwi', 'orange', 'pear']