分治、递归算法专题 (I):Leetcode 50 Pow(x, n) + Leetcode 14 最长公共前缀

分治、递归算法专题 (I):Leetcode 50 Pow(x, n) + Leetcode 14 最长公共前缀

Leetcode 50 Pow(x, n)

题目描述

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例 1:

输入: 2.10000, 3
输出: 9.26100

示例 2:

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25

说明:

-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。

题解

典型的分治算法:时间复杂度 O ( log ⁡ N ) O(\log{N}) O(logN)

对于正幂来说:

{ x n = x n / 2 ∗ x n / 2 if  n  mod  2  =  0 x n = x n / 2 ∗ x n / 2 ∗ x if  n  mod  2  =  1 \begin{cases} x^{n} = x^{n/2}*x^{n/2}&\text{if $n$ mod $2$ = $0$}\\ x^{n} = x^{n/2}*x^{n/2}*x&\text{if $n$ mod $2$ = $1$}\\ \end{cases} {xn=xn/2xn/2xn=xn/2xn/2xif n mod 2 = 0if n mod 2 = 1

注意点:

  1. 需要讨论一下 x = 0 x=0 x=0的情况(因为有一个测试的例子是 0.000000 1 2147483647 0.0000001^{2147483647} 0.00000012147483647)如果不加,时间会超时。

  2. 对于负幂( n < 0 n<0 n<0), x n = 1 x − n x^n=\frac{1}{x^{-n}} xn=xn1,这样就很简单了。

def myPow(x, n):
    def posPow(x, n):
        if n == 1:
            return x
        elif n == 0:
            return 1
        else:
            temp = posPow(x, n // 2)
            if n % 2:
                return x * temp * temp
            else:
                return temp * temp
    if x == 1:
        return 1
    if x == 0:
        return 0
    if n > 0:
        return posPow(x, n)
    else:
        return 1 / posPow(x, -n)

执行结果

执行用时 : 20 ms

内存消耗 :11.8 MB

在这里插入图片描述

Leetcode 14 最长公共前缀

题目描述

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。

示例 1:

输入: ["flower","flow","flight"]
输出: "fl"

示例 2:

输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。

题解

分治算法,当前列表的最长公共前缀,等于左边一半与右边一半的最长公共前缀的最长公共前缀。

L C P ( l i s t ) = C o m m o n ( L C P ( l i s t [ 0 , n / 2 ] ) , L C P ( l i s t [ n / 2 , n ] ) ) LCP(list)=Common\left(LCP(list[0,n/2]),LCP(list[n/2,n])\right) LCP(list)=Common(LCP(list[0,n/2]),LCP(list[n/2,n]))

如果列表长度为2,则对单词从头到尾遍历一次,找公共前缀;如果长度为1,则输出列表的第一个元素。

时间复杂度递推式:

T ( N ) = 2 T ( N / 2 ) + O ( M ) T(N)=2T(N/2) + O(M) T(N)=2T(N/2)+O(M)

由主定理,时间复杂度为: Θ ( N log ⁡ M ) \Theta(N\log M) Θ(NlogM) ,其中 M M M 为最长公共前缀长度。

代码如下:

class Solution(object):
    def longestCommonPrefix(self, strs):
        def common(s1, s2):
            n = min(len(s1), len(s2))
            s = ""
            for i in range(0, n):
                if s1[i] == s2[i]:
                    s = s + s1[i]
                else:
                    break
            return s
        if not strs:
            return ""
        n = len(strs)
        if n == 2:
            return common(strs[0], strs[1])
        elif n == 1:
            return strs[0]
        return common(self.longestCommonPrefix(strs[:n//2]), self.longestCommonPrefix(strs[n//2:]))

执行结果

执行时间:24 ms

内存消耗:11.9 MB

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值