概述
该博客结合leetcode原题介绍了可以使用“分治”思想解决的常见题目。
例题
2.1 n次幂
#Leetcode 50 Pow(x, n)
(1)暴力解法
多少次幂,就乘上多少次x。但是提交的话会超时。
*时间复杂度:O(N)
*空间复杂度:O(1)
class Solution(object):
def myPow(self, x, n):
"""
:type x: float
:type n: int
:rtype: float
"""
res = 1
if n<0:
for _ in xrange(-n):
res = res * x
return 1.0/float(res)
elif n==0:
return 1
else:
for _ in xrange(n):
res = res * x
return res
(2)分治,用递归实现
将问题拆成两个子问题,再拆两个子问题。
*时间复杂度:O(logN),很遗憾,依然超时。
*空间复杂度:O(1)
class Solution(object):
def subPow(self, x, n):
if n==0:
return 1
if n%2==0:
return self.subPow(x, int(n/2)) * self.subPow(x, int(n/2))
else:
return x * self.subPow(x, int(n / 2)) * self.subPow(x, int(n / 2))
def myPow(self, x, n):
"""
:type x: float
:type n: int
:rtype: float
"""
res = self.subPow(x, abs(n))
if n>0:
return res
elif n==0:
return 1
else:
return 1.0/float(res)
(3)分治,不用递归实现
*时间复杂度:O(logN)
*空间复杂度:O(1)
class Solution(object):
def myPow(self, x, n):
"""
:type x: float
:type n: int
:rtype: float
"""
if n<0:
x = 1/x
n = -n
pow = 1
while n:
if n & 1:
pow *= x
x *= x
n>>=1
return pow
2.2 求众数
#Leetcode 169 求众数
(1)暴力解法
对数列中每个数循环一遍,找到大于n/2个数的数字。
*时间复杂度:O(N^2)
*空间复杂度:O(1)
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
max_cnt = 0
max_num = 0
for i in range(len(nums)):
cnt = 0
for j in range(len(nums)):
if nums[i]==nums[j]:
cnt += 1
if cnt>max_cnt:
max_cnt = cnt
max_num = nums[i]
if max_cnt>len(nums)/2:
return max_num
return max_num
(2)排序解法
将数组排序,找到最长连续段。
*时间复杂度:O(NlogN)
*空间复杂度:O(1)
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums.sort()
cnt = 1
for i in range(1, len(nums)):
if nums[i]==nums[i-1]:
cnt += 1
else:
if cnt>len(nums)/2:
return nums[i-1]
cnt = 1
if cnt>len(nums)/2:
return nums[-1]
(3)使用hashmap
使用hashmap存储每个元素的次数。
*时间复杂度:O(N)
*空间复杂度:O(N)
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
mem = {}
for v in nums:
if v in mem:
mem[v] += 1
else:
mem[v] = 1
for k, v in mem.items():
if v>len(nums)/2:
return k
(4)分治递归