• LeetCode专题-Python实现之第14题:Longest Common Prefix


    导航页-LeetCode专题-Python实现

    相关代码已经上传到github:https://github.com/exploitht/leetcode-python
    文中代码为了不动官网提供的初始几行代码内容,有一些不规范的地方,比如函数名大小写问题等等;更合理的代码实现参考我的github repo

    1、读题

    Write a function to find the longest common prefix string amongst an array of strings.

    很简单的一句话,寻找一个字符串数组的最大公共前缀字符子串
    举个简单的例子,如下字符串列表:
    ['abc', 'abcd', 'abd']
    的最大公共前缀是'ab'

    2、解题

    最简单粗暴的方式,遍历嘛,搞一个前缀,前缀从短变长,去匹配整个字符串数组,就能找到公共前缀。基于这种思路,有了如下代码:

    class Solution(object):
        def longestCommonPrefix(self, strs):
            """
            :type strs: List[str]
            :rtype: str
            """
            # 空列表判断
            if not strs:
                return ''
            # 取第一个字符串来寻找前缀
            first_str = strs[0]
            prefix = ''
            for i in range(len(first_str)):
                prefix = first_str[:i + 1]
                # 如果strs中每一个字符串都是以prefix开头,那么prefix就是前缀
                if all(map(lambda x: x.startswith(prefix), strs)):
                    continue
                else:
                    break
            else:
                return prefix
            return prefix[:-1]
    

    3、第一次优化

    上面这种实现方式用一次循环来取出一个前缀,然后循环遍历字符串数组判断前缀是否正确,也就是O(n2)的时间复杂度(n的平方)

    能不能优化一点呢,思考有序比无序简单,是否可以先排序?Python的sorted函数排序性能可是杠杠的,Timsort算法在最坏情况也有n log n的表现,快排一般也是这个复杂度,但是最坏情况是n平方。

    如果有序,怎样寻找前缀呢?观察一个有序的例子:['abcd','abce','abd','ad'],第一个和第二个比较,能够得到的子串一般相对较长,但是越往后呢,对了,不会变长,只会变短或者不变。也就是首尾对比就能够得到结果。于是乎有了下面解题方式:

    class Solution(object):
        def longestCommonPrefix(self, strs):
            """
            :type strs: List[str]
            :rtype: str
            """
            # 如果字符串数组为空,或者有一个元素但是是空字符串,则返回空字符串
            # 先排序
            strs_list = sorted(strs)
            if not strs or not strs[0]:
                return ''
            # # 先排序
            # strs_list = sorted(strs)
            # 前缀初始化为空字符串,然后循环递增
            prefix = ''
            for i in range(len(strs_list[0])):
                prefix = strs_list[0][:i + 1]
                # 判断排序后的字符串数组首尾是否有公共前缀,all判断比and快
                # if all([strs_list[0].startswith(prefix), strs_list[-1].startswith(prefix)]):
                if strs_list[0].startswith(prefix) and strs_list[-1].startswith(prefix):
                    continue
                else:
                    # 不满足if,也就是prefix多加了一位的情况,对应最后一行的 return prefix[:-1]
                    break
            else:
                # 不是break结束循环,则执行这里
                return prefix
            return prefix[:-1]
    

    如上实现,排序的时间复杂度是O(n)或者O(n log n),寻找子串的时间复杂度是O(n)级别,合在一起也就是O(n)或者O(n + n log n)

  • 相关阅读:
    跨期套利策略
    读书笔记 量化交易:如何建立自己的算法交易事业
    ESP8266固件修改可以控制多个IO方法
    ESP8266固件烧录方法
    关于毕设WiFi选型
    关于(x&y)+((x^y)>>1)的探究
    QML添加右键菜单
    初学QML之QML和C++混合方法
    初学QML之qmlRegisterType
    我的第一个QML Button的实现
  • 原文地址:https://www.cnblogs.com/cloudgeek/p/7600516.html
Copyright © 2020-2023  润新知