分治

LeetCode练习:分治

分治(分而治之)是将一个规模较大的问题拆分成几个小问题,然后求解规模较小的小问题,最后将每个小问题的解合并,即得到大问题的解
个人感觉在解决问题中使用分治思想的难点在于

  • 证明能够使用分治算法的可行性
  • 在得到小问题的解后如何将小问题的解合并
    分治算法的主要实现手段是递归

归并排序

最经典的应用分治算法的例子就是归并排序

      from math import floor

      def mergesort(arr):
          if len(arr) < 2:
              return arr
          else:
              middle = floor(len(arr) / 2)
              left = arr[0:middle]
              right = arr[middle:]
              return merge(mergesort(left), mergesort(right))

      def merge(left, right):
          result = []
          while left and right:
              if left[0] <= right[0]:
                  result.append(left.pop(0))
              else:
                  result.append(right.pop(0))

          while left:
              result.append(left.pop(0))
          while right:
              result.append(right.pop(0))

          return result

以下是练习题目:

1.求众数

在一个数组中找到出现次数最多的元素
思路:

  • 确定拆分的终止条件
  • 将数组一分为二,直到满足终止条件
  • 处理子问题得到子结果,并合并:
    1. 数组长度为1,则输出数组
    2. 若left == right, 则输出left
    3. 若arr.count(left) > arr.count(right), 则输出left
    4. 否则输出right
'''
用分治的思想求数组中的众数
'''
from math import floor

def findmode(arr):
    if len(arr) < 2:
        return arr[0]
    else:
        middle = floor(len(arr)/2)
        left = findmode(arr[0 : middle])
        right = findmode(arr[middle : ])
        return merge(left, right, arr)

def merge(left, right, arr):
    if left == right:
        return left
    elif arr.count(left) > arr.count(right):
        return left
    else:
        return right

print(findmode([1,1,2,3,4,5]))

2.最大子序列和

求出一个数组的子序列中,和最大的子序列,输出和
思路:

  • 确定终止条件
    数组长度为1时,终止拆分
  • 拆分问题
    将数组一分为二,直至满足终止条件
  • 求出子问题的解,合并子问题的解
    1. 合并
      • 从右到左求出left数组的最大子序列和
      • 从左到右求出right数组的最大子序列和
      • 合并两个子序列
    2. 输出左区间,右区间以及合并的子序列的最大值
'''
给定一个整数数组,找到一个具有最大和的连续子数组
'''

def maxsubarray(arr):
    if len(arr) < 2:
        return arr[0]
    else:
        middle = len(arr)//2
        left = maxsubarray(arr[ : middle])
        right = maxsubarray(arr[middle : ])
        max_l = arr[len(arr)//2-1]
        tmp = 0
        for i in range(len(arr)//2-1, -1, -1):
            tmp += arr[i]
            max_l = max(tmp, max_l)

        max_r = arr[len(arr)//2]
        tmp = 0
        for i in range(len(arr)//2, len(arr)):
            tmp += arr[i]
            max_r = max(tmp, max_r)

        return max(left, right, max_l+max_r)

print(maxsubarray([-2,1,-3,4,-1,2,1,-5,4]))

3.实现pow(x, n)

'''
实现计算x的n次幂函数
'''

def mypow(x, n):
    if n < 0:
        x = 1/x
        n = -n

    if n == 0:
        return 1

    if n%2 == 1:
        p = x * mypow(x, n-1)
        return p
    
    return mypow(x*x, n/2)

print(mypow(2, 10))
posted @ 2020-08-19 21:55  C_初学者  阅读(154)  评论(0)    收藏  举报