牛客网刷题--python

安置路灯

题目描述
小Q正在给一条长度为n的道路设计路灯安置方案。

为了让问题更简单,小Q把道路视为n个方格,需要照亮的地方用’.'表示, 不需要照亮的障碍物格子用’X’表示。

小Q现在要在道路上设置一些路灯, 对于安置在pos位置的路灯, 这盏路灯可以照亮pos - 1, pos, pos + 1这三个位置。

小Q希望能安置尽量少的路灯照亮所有’.'区域, 希望你能帮他计算一下最少需要多少盏路灯。

输入描述:
输入的第一行包含一个正整数t(1 <= t <= 1000), 表示测试用例数
接下来每两行一个测试数据, 第一行一个正整数n(1 <= n <= 1000),表示道路的长度。
第二行一个字符串s表示道路的构造,只包含’.‘和’X’。
输出描述:
对于每个测试用例, 输出一个正整数表示最少需要多少盏路灯。

示例1
输入
2
3
.X.
11
…XX…XX

输出
1
3

解法
比较简单的贪心算法,判断好边界条件即可


t = int(input().strip())
for _ in range(t):
    n = int(input().strip())
    s = input().strip()
    res = 0
    flag = 0
    for i in range(n):
        if flag == 0 and s[i] == '.':
            if i == n - 1:
                res += 1
            else:
                flag = 1
        elif flag == 1:
            res += 1
            flag = 2
        elif flag == 2:
            flag = 0
            
    print(res)

牛妹的蛋糕

题目描述
众所周知,牛妹非常喜欢吃蛋糕。
第一天牛妹吃掉蛋糕总数三分之一多一个,第二天又将剩下的蛋糕吃掉三分之一多一个,以后每天吃掉前一天剩下的三分之一多一个,到第n天准备吃的时候只剩下一个蛋糕。
牛妹想知道第一天开始吃的时候蛋糕一共有多少呢?

示例1
输入
2
输出
3

示例2
输入
4
输出
10

备注:
0

解法
动态规划的思路,实际上反过来想,第一天是1,求第n天的总数。

#
# 
# @param n int整型 只剩下一只蛋糕的时候是在第n天发生的.
# @return int整型
#
class Solution:
    def cakeNumber(self , n ):
        # write code here
        # x = y - (y / 3 + 1), y = (x + 1) * 3 / 2
        res = 1
        for i in range(n - 1):
            res = int((res + 1) * 3 / 2)
        return res

牛妹的礼物

题目描述
众所周知,牛妹有很多很多粉丝,粉丝送了很多很多礼物给牛妹,牛妹的礼物摆满了地板。
地板是N\times MN×M的格子,每个格子有且只有一个礼物,牛妹已知每个礼物的体积。
地板的坐标是左上角(1,1) 右下角(N, M)。
牛妹只想要从屋子左上角走到右下角,每次走一步,每步只能向下走一步或者向右走一步或者向右下走一步
每次走过一个格子,拿起(并且必须拿上)这个格子上的礼物。
牛妹想知道,她能走到最后拿起的所有礼物体积最小和是多少?

示例1
输入
[[1,2,3],[2,3,4]]
输出
7
说明
(1,1)->(1,2)->(2,3)

备注:
0 每个礼物的体积小于100

解法
动态规划

#
# 
# @param presentVolumn int整型二维数组 N*M的矩阵,每个元素是这个地板砖上的礼物体积
# @return int整型
#
class Solution:
    def selectPresent(self , presentVolumn ):
        # write code here
        if not presentVolumn:
            return 0
        N, M = len(presentVolumn), len(presentVolumn[0])
        dp = [[0 for i in range(M)] for j in range(N)]
        for i in range(N):
            for j in range(M):
                if i > 0 and j > 0:
                    dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + presentVolumn[i][j]
                elif i > 0 :
                    dp[i][j] = dp[i - 1][j] + presentVolumn[i][j]
                elif j > 0 :
                    dp[i][j] = dp[i][j - 1] + presentVolumn[i][j]
                else:
                    dp[i][j] = presentVolumn[i][j]
        return dp[N - 1][M - 1]

最大数

题目描述
给定一个包含大写英文字母和数字的句子,找出这个句子所包含的最大的十六进制整数,返回这个整数的值。数据保证该整数在int表示范围内

示例1
输入
“012345BZ16”
输出
1193051
说明
12345B对应十进制为1193051

备注:
0<字符串长度<=105

解法
不要用字符串进行大小的比较,直接转成数字来比,时间够

#
# 
# @param s string字符串 
# @return int整型
#
class Solution:
    def solve(self , s ):
        # write code here
        tmp = ""
        res = 0
        chars = [str(x) for x in range(10)] + ['A', 'B', 'C', 'D', 'E', 'F']
        for i in range(len(s)):
            if s[i] in chars:
                tmp += s[i]
            else:
                if tmp != "":
                    res = max(res, self.c2int(tmp))
                tmp = ""
                
        return res

    def c2int(self, res):
        num = 0
        for i in range(len(res)):
            x = res[i]
            if x in [str(x) for x in range(10)]:
                x = int(x)
            else:
                x = 10 + (ord(x) - ord('A'))
            num = num * 16 + x
        return num

神奇的数字

题目描述
在这个特殊的假期里,由于牛牛在家特别无聊,于是他发明了一个小游戏,游戏规则为:将字符串数字中为偶数位的数字进行翻转,将翻转后的结果进行输出。

示例1
输入
“1234”
输出
“1432”
说明
第2、4位为偶数,所以将其翻转后,得到 1432

示例2
输入
“12346”
输出
“16342”
说明
第2、4、5位为偶数,所以将其翻转后,得到 16342

备注:
数字的长度<=10^7 且不包含数字0

解法
就是个双指针,一个从左往右,一个从右往左,遇到偶数就交换一下。

#
# 
# @param number string字符串 
# @return string字符串
#
class Solution:
    def change(self , number ):
        # write code here
        if not number or len(number) == 1:
            return number
        nums = [int(x) for x in number]
        i, j = 0, len(nums) - 1
        while i < j:
            while i < j and nums[i] % 2 == 1:
                i += 1
            while i < j and nums[j] % 2 == 1:
                j -= 1
            
            nums[i], nums[j] = nums[j], nums[i]
            i += 1
            j -= 1
            
        nums = [str(x) for x in nums]
        return ''.join(nums)

牛能和牛可乐的礼物

题目描述
众所周知,牛能和牛可乐经常收到小粉丝们送来的礼物,每个礼物有特定的价值,他俩想要尽可能按照自己所得价值来平均分配所有礼物。

那么问题来了,在最优的情况下,他俩手中得到的礼物价值和的最小差值是多少呢?
p.s 礼物都很珍贵,所以不可以拆开算哦

示例1
输入
[1,2,3,4]
输出
0
说明
他俩一个人拿1,4 。另一个人拿2,3

示例2
输入
[1,3,5]
输出
1
说明
他俩一个人拿1,3.另一个人拿5

备注:
单个礼物价值不超过100,礼物个数小于100,所有礼物总价值不超过10000

解法
01背包的变形:体积和价值都是题目中给的“礼物价值”。
把总体积的一半作为背包容量,挨个判断当前的礼物是否要放入到背包。最后背包中m体积所容纳的就是最多的礼物。

#
# 
# @param presentVec int整型一维数组 每个礼物的价值
# @return int整型
#
class Solution:
    def maxPresent(self , presentVec ):
        # write code here
        n = len(presentVec)
        m = int((sum(presentVec) + 1)/ 2)
        dp = [0 for i in range(m + 1)]
        
        for i in range(n):
            for j in range(m, -1, -1):
                if presentVec[i] > j:
                    continue
                dp[j] = max(dp[j], dp[j - presentVec[i]] + presentVec[i])
                
        a = dp[m]
        b = sum(presentVec) - a
        return abs(a - b)

牛妹的面试

题目描述
众所周知,牛妹是一个offer收割姬,这次面试她遇到了这样的一个问题。
给了一个序列,让找出最长的“凸子序列”
何为“凸子序列”:数列中有一个xi,使得所有x0xi+1>xi+1>….>xn
eg:12345431,是山峰序列,12345234不是山峰序列
注:单调递增或单调递减序列也算山峰序列;单独一个数是长度为1的山峰序列

示例1
输入
[1,2,3,6,1]
输出
5

示例2
输入
[1,2,2,1]
输出
3
说明
1,2,1

备注:
给定的序列中数都大于0 且不超过10000,且序列长度不超过1000

解法
开始想的是先求出列表中的最大值,那么从最大值的位置分开,左右两边分别得到最长递增序列的长度就可以了。后来发现这个会有很多边界问题,处理起来比较麻烦。
从网上发现,其实就从左到右,从右到左分别得到两个递增序列的dp数组,然后在每个位置分别相加,得到的就是山峰长度。

#
# 返回最大山峰序列长度
# @param numberList int整型一维数组 给定的序列
# @return int整型
#
class Solution:
    def mountainSequence(self , numberList ):
        # write code here
        if len(numberList) <= 1:
            return len(numberList)
        n = len(numberList)
        res = 0
        dp1 = self.dp_fuc(numberList)
        dp2 = self.dp_fuc(numberList[::-1])
        for i, x in enumerate(numberList):
            tmp = dp1[i] + dp2[n - i - 1]
            res = max(res, tmp)

        return res - 1
    
    def dp_fuc(self, sublist):
        n = len(sublist)
        if n == 0:
            return 0
        dp = [1] * n
        for i in range(1, n):
            for j in range(0, i):
                if sublist[j] < sublist[i]:
                    dp[i] = max(dp[i], dp[j] + 1)
                    
        return dp

字符串距离计算

题目描述
给定两个长度相等的,由小写字母组成的字符串S1和S2,定义S1和S2的距离为两个字符串有多少个位置上的字母不相等。
现在牛牛可以选定两个字母X1和X2,将S1中的所有字母X1均替换成X2。(X1和X2可以相同)
牛牛希望知道执行一次替换之后,两个字符串的距离最少为多少。

示例1
输入
“aaa”,“bbb”
输出
0
说明
牛牛可以将S1中的字符’a’全部替换成字符’b’,这样S1就变成了"bbb",那么S1和S2的距离就是0

示例2
输入
“aabb”,“cdef”
输出
3
说明
一种可行的方案是将S1中的字符’a’全部替换成字符’c’,那么S1变成了"ccbb",和S2的距离是3

备注:
牛客网刷题--python_第1张图片
解法
参考标准题解:
对于所有可能的X1, X2, 记录cnt[X1][X2]有多少个位置i, 使得S1[i] == X1, S2[i] == X2
这一步只需扫描一遍字符串即可计算得到
然后枚举可能的X1, X2,这时距离 = 原本的距离 + cnt[X1][X1] - cnt[X1][X2]
时间复杂度O(N)

#
# 计算最少的距离
# @param S1 string字符串 第一个字符串
# @param S2 string字符串 第二个字符串
# @return int整型
#
class Solution:
    def GetMinDistance(self , S1 , S2 ):
        # write code here
        cnt = [[0 for i in range(26)] for j in range(26)]
        
        ans = 0
        for i in range(len(S1)):
            x, y = S1[i], S2[i]
            xx, yy = ord(x) - ord('a'), ord(y) - ord('a')
            cnt[xx][yy] += 1
            if xx != yy:
                ans += 1
        
        res = ans
        for i in range(26):
            for j in range(26):
                res = min(res, ans + cnt[i][i] - cnt[i][j])
                
        return res
    

用两个栈实现队列

题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

解法
开始没怎么看明白题目,所以看了题解。栈A用来作入队列。栈B用来出队列,当栈B为空时,栈A全部出栈到栈B,栈B再出栈(即出队列)。这个想法还是比较巧妙的。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []
    def push(self, node):
        # write code here
        self.stack1.append(node)
    def pop(self):
        # return xx
        if self.stack2 == []:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

旋转数组的最小数字

题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

解法
其实就是用二分法。注意这里面数组中可能会存在重复的数字,所以会有另外一个情况。

  • mid值大于前一个值,直接输出
  • mid值大于left位置的值:说明我们需要找的值在mid的右边,l=mid+1
  • mid值小于left位置的值:说明我们需要找的值在mid的左边,r=mid-1
  • mid值等于left位置的值:此时无法判断在左边还是右边,就缩小寻找的范围,也就是left-=1;right-=1
# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if len(rotateArray) == 0:
            return 0
        l, r = 0, len(rotateArray) - 1
        while l <= r:
            mid = (l + r) // 2
            if rotateArray[mid - 1] > rotateArray[mid]:
                return rotateArray[mid]
            elif rotateArray[l] < rotateArray[mid]:
                l = mid + 1
            elif rotateArray[l] > rotateArray[mid]:
                r = mid - 1
            else:
                l -= 1
                r -= 1
                

变态跳台阶

题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

解法
使用数学归纳法,台阶为n时,BT(n) = BT(n-1) + BT(n-2) + … + BT(1) + 1 = 2BT(n-1)
得到:当n>=1时,变态跳台阶的通式是:
BT(n) = 2
BT(n-1) n>0

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloorII(self, number):
        # write code here
        if number == 1:
            return 1
        return 2 * self.jumpFloorII(number - 1)

另一种题目问法:

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

思路:(斐波拉契数列)

当只有一级台阶时(n=1),此时青蛙跳一次就可以完成目标;当只有两级台阶时(n=2),青蛙可以一次跳一级台阶分两次完成也可以一次跳两级台阶,此时有两种跳法使得青蛙可以达成目标;

当n>2时,此时我们可以把n级台阶的跳法看成是n的函数:f(n);如果青蛙第一步跳一级台阶,之后的跳法数目就是之后剩余n-1级台阶的跳法数目,即f(n-1);另一种可能的情况就是青蛙第一步跳两级台阶,之后的跳法数目就是之后剩余的n-2级台阶的跳法数目;所以n级台阶的不同跳法的总数是f(n)=f(n-1)+f(n-2)

不用加减乘除做加法

题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

解法
参考:https://zhuanlan.zhihu.com/p/112407870
因为不允许采用四则运算,所以只能考虑位运算了。

其实就是用二进制来模拟加法操作。首先将两个数最低位相加,如果都是 1,那么就得到0,并且进位1,然后接着算下一位。

但是这样一位一位模拟不方便实现,更简单的实现方法是直接把两个数对应位相加,不管进位。然后进位单独计算,如果某一位两个数都是1,那么进位就会对下一位产生影响。然后接着算不进位求和加上进位的值,再计算新的进位,依次重复下去,直到进位为0为止。

用一个实际的例子来演示一下,计算3+7的值,其中s表示每一步不考虑进位的求和,c表示每一步的进位,最后得到结果,也就是十进制的10 :
牛客网刷题--python_第2张图片

# -*- coding:utf-8 -*-
class Solution:
    def Add(self, num1, num2):
        # write code here
        while num2 != 0:
            temp = num1 ^ num2
            num2 = (num1 & num2) << 1
            num1 = temp & 0xFFFFFFFF
        return num1 if num1 <= 0x7FFFFFFF else ~(num1 ^ 0xFFFFFFFF)

二叉树的镜像

题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
牛客网刷题--python_第3张图片
解法
就直接递归的交换处理左右子树就可以

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        # write code here
        if root == None:
            return root
        
        root.left, root.right = root.right, root.left
        root.left = self.Mirror(root.left)
        root.right = self.Mirror(root.right)
        
        return root

构建乘积数组

题目描述
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2];)

解法
其实就是提前准备好两个全乘好的数组,然后再从左到右过一遍A,得到对应位置上两个数组的乘积。

# -*- coding:utf-8 -*-
class Solution:
    def multiply(self, A):
        # write code here
        l, r = [], []
        n = len(A)
        tmp = 1
        l.append(tmp)
        for i, x in enumerate(A):
            tmp *= x
            l.append(tmp)
            
        tmp = 1
        for i in range(len(A)-1, -1, -1):
            tmp *= A[i]
            r.append(tmp)
        r.append(1)
            
        res = []
        for i in range(len(A)):
            tmp = l[i] * r[n - i - 2]
            res.append(tmp)
            
        return res

连续子数组的最大和

题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

解法
就是简单的动态规划

# -*- coding:utf-8 -*-
class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        dp = [0] * len(array)
        for i, x in enumerate(array):
            if i == 0:
                dp[i] = x
                ma = x
            dp[i] = max(x, dp[i - 1] + x)
            if dp[i] > ma:
                ma = dp[i]
            
        return ma

跳台阶

题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

解法
就是斐波那契数列,但是如果直接递归会超时,所以迭代。

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, number):
        # write code here
        res = []
        for i in range(1, number + 1):
            if i in [0, 1, 2]:
                res.append(i)
            else:
                res.append(res[-1] + res[-2])
                
        return res[-1]
        '''
        if number in [0, 1, 2]:
            return number
        return self.jumpFloor(number - 1) + self.jumpFloor(number - 2)
        '''

矩形覆盖

我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

比如n=3时,2*3的矩形块有3种覆盖方法
牛客网刷题--python_第4张图片

解法
和上面的题一样,不过这个要找规律,可以发现n=0, f=0; n=1, f=1; n=2, f=2; n=3, f=3; n=4; f=5… 就比如n=4的时候,其中3个可以在n=3的情况下加上一个竖着的,另外2个就是在n=2的情况下加上两个横着的。

# -*- coding:utf-8 -*-
class Solution:
    def rectCover(self, number):
        # write code here
        res = []
        for i in range(0, number + 1):
            if i in [0, 1, 2]:
                res.append(i)
            else:
                res.append(res[-1] + res[-2])
                
        return res[-1]

平衡二叉树

题目描述
输入一棵二叉树,判断该二叉树是否是平衡二叉树。

在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树

解法
在二叉搜索树那块也做过这个题,就是两个递归调用,一次是求深度,一次是求子树是否平衡。问题是求深度那个递归需要调用好几次,而且其中可能会有些重复计算。
所以可以用自底向上的方法来求,利用后序遍历:左子树、右子树、根节点,可以先递归到叶子节点,然后在回溯的过程中来判断是否满足条件。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def depth(self, root):
        if not root:
            return 0
        return max(self.depth(root.left), self.depth(root.right)) + 1
    
    def IsBalanced_Solution(self, pRoot):
        # write code here
        if not pRoot:
            return True
        if abs(self.depth(pRoot.left) - self.depth(pRoot.right)) > 1:
            return False
        return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
        

方法2:

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def depth(self, root):
        if not root:
            return 0
        l = self.depth(root.left)
        if l == -1:
            return -1
        r = self.depth(root.right)
        if r == -1:
            return -1
        if abs(l - r) > 1:
            return -1
        return max(l, r) + 1
        
        
    def IsBalanced_Solution(self, pRoot):
        # write code here
        if not pRoot:
            return True
        if self.depth(pRoot) == -1:
            return False
        return True

二进制中1的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

解法
第一种,可以将n上的每一位与1取与,统计1的个数;在求解的过程中每次循环时1左移一位,即n<<1
第二种,如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。
举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        # write code here
        if n < 0:
            n = n & 0xffffffff
        res = 0
        while n != 0:
            n = n & (n - 1)
            res += 1
            
        return res

两个链表的第一个公共节点

输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)

解法
就是首先构造出相同长度的链表,这样的话就用双指针同时在两个链表遍历肯定会有公共节点了。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        l1, l2 = 0, 0
        cur1 = pHead1
        while cur1:
            l1 += 1
            cur1 = cur1.next
        cur2 = pHead2
        while cur2:
            l2 += 1
            cur2 = cur2.next
        
        tmp = abs(l1 - l2)
        if l1 > l2:
            while tmp > 0:
                pHead1 = pHead1.next
                tmp -= 1
        else:
            while tmp > 0:
                pHead2 = pHead2.next
                tmp -= 1
                
        while pHead1 and pHead2:
            if pHead1 == pHead2:
                return pHead1
            pHead1 = pHead1.next
            pHead2 = pHead2.next
            
            

数值的整数次方

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

保证base和exponent不同时为0

解法
参考:https://www.nowcoder.com/questionTerminal/1a834e5e3e1a4b7ba251417554e07c00?answerType=1&f=discussion

首先做预处理:求pow(b, n),如果n为负数怎么解决
然后是两种方法:

  • 直接暴力循环n次求解
  • 快速幂的递归法求解,注意处理奇偶情况
# -*- coding:utf-8 -*-
class Solution:
    def Power(self, base, exponent):
        # write code here
        if exponent == 0:
            return 1.0
        if exponent < 0:
            base = 1 / base
            exponent = -exponent
        tmp = self.Power(base, exponent/2)
        if exponent % 2 == 0:
            res = tmp * tmp
        else:
            res = tmp * tmp * base
            
        return res

你可能感兴趣的:(Python,牛客网,python)