分治、递归算法专题 (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/2∗xn/2xn=xn/2∗xn/2∗xif n mod 2 = 0if n mod 2 = 1
注意点:
-
需要讨论一下 x = 0 x=0 x=0的情况(因为有一个测试的例子是 0.000000 1 2147483647 0.0000001^{2147483647} 0.00000012147483647)如果不加,时间会超时。
-
对于负幂( n < 0 n<0 n<0), x n = 1 x − n x^n=\frac{1}{x^{-n}} xn=x−n1,这样就很简单了。
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