Leetcode学习--分治(8.18-8.19)

分治

一、主要思想

1)、 分治算法的主要思想是将一个大问题递归的分为若干个小问题,然后再对小问题逐个击破,最后算法再层层合并为原来的大问题。简而言之就是分而治之。
2)、伪代码

def divide_conquer(problem, paraml, param2,...):
    # 不断切分的终止条件
    if problem is None:
        print_result
        return
    # 准备数据
    data=prepare_data(problem)
    # 将大问题拆分为小问题
    subproblems=split_problem(problem, data)
    # 处理小问题,得到子结果
    subresult1=self.divide_conquer(subproblems[0],p1,..)
    subresult2=self.divide_conquer(subproblems[1],p1,...)
    subresult3=self.divide_conquer(subproblems[2],p1,.)
    # 对子结果进行合并 得到最终结果
    result=process_result(subresult1, subresult2, subresult3,...)

二、刷题练习

1. Pow(x, n)

1)、 Pow(x, n)
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
2)、示例:

示例 1:

输入: 2.00000, 10
输出: 1024.00000
示例 2:

输入: 2.10000, 3
输出: 9.26100
示例 3:

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

3)、思想:
求x的n次幂可以将其分解为求x的n/2次幂和x的n/2次幂的乘积,对于x的n/2次幂同样可以拆分为两个x的n/4次幂的乘积。以此类推将x的n次幂递归的拆分并求结果,最后再合并。需要注意的是n=0的情况以及n为负数的情况。

4)、代码

class Solution(object):
    def myPow(self, x, n):
        # 处理n为负的情况
        if n < 0 :
            x = 1/x
            n = -n
        # 当切分到n=0时,切分终止
        if n == 0 :
            return 1
        # 将大问题切分为小问题
        if n%2 ==1:
          # 计算每一个子问题
          # 递归调用
          p = x * self.myPow(x,n-1)
          return p
        return self.myPow(x*x,n/2)

5)、来源
力扣(leetcode):https://leetcode-cn.com/problems/powx-n/

2. 最大子序和

1)、最大子序和:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
2)、示例:

输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6

3)、思想:
本题采用动态规划的思想。将指针i从头开始遍历元素,如果前i-1个元素之和大于0,那么就将指针i所指的第i个元素与之前的相加。若前i-1个元素之和小于0,则不相加,保持当前的元素不变。最后取和最大的那个数组。
4)、代码:

class Solution(object):
    def maxSubArray(self, nums):
    	"""
        :type nums: List[int]
        :rtype: int
        """
        #如果数组不存在,返回零
        if not nums:
            return 0
        #如果数组长度为1,返回数组第一个数的值
        elif len(nums)==1:
            return nums[0]
        #获取数组长度
        n = len(nums)
        #遍历数组
        for i in range(1,n):
            #如果前i个元素之和大于0
            if nums[i-1] > 0:
                #将第i个与之前的相加
                nums[i] += nums[i-1]
        #取所有数组结果中的最大值
        return max(nums)

5)、来源
力扣(leetcode):https://leetcode-cn.com/problems/maximum-subarray/

3.多数元素

1)、多数元素
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 [n/2] 的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
2)、示例:

示例 1:
输入: [3,2,3]
输出: 3

示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2

3)、思想:
对于本题,我认为可以设置一个字典保存当前记录的某一元素出现次数,最后返回最大值。
还有一种方法是直接先将数组排序,排序后值相同的元素都聚在一起,我们只需记录比较即可。

4)、代码:

#使用字典
class Solution(object):
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        #设置一个字典,空值
        dicts = {}
        #遍历数组
        for i in nums:
            #记录每一个元素出现的次数
            dicts[i] = dicts.get(i,0) + 1
        #返回出现次数最多的,即众数
        return (max(dicts, key=dicts.get))

5)、来源
力扣(leetcode):https://leetcode-cn.com/problems/majority-element/

你可能感兴趣的:(算法,leetcode)