题目:
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。
示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000
思路:既不能使用库函数,也要让时间复杂度降低,还要不需要考虑大数问题
首先第一种思路:直接return x**n,反正也可以通过,但是想考察的肯定不是这个
第二种思路:使用快速幂连上二分法来计算,如果我们要计算x^64,那我们可以第一次计算出x,第二次是x^2,第三次就是x^4,下一次就是x^8,每次把这次计算出来的值作为底数,就不用再计算64次了。也就把题目转变为了(X^2)^(n/2),所以每次计算一次之后幂就变为了n/2,但是还要考虑n是奇数还是偶数的问题,如果是奇数,那最后肯定要多乘上一个x,如果是偶数那就不用乘,所以这里还多引入了一个res
代码:
class Solution:
def myPow(self, x: float, n: int) -> float:
if x==0:return 0
res=1
if n<0:n,x=-n,1/x
while n:
if n&1:res*=x
x*=x
n=n//2
return res
题目二:重建二叉树,也就是利用三种遍历队列中的两种实现二叉树的重建
本题的前提是两个遍历中不会产生重复的数,产生了那这个递归的方法也就不能使用了
思路:
先序中的第一个就是根节点,在中序中找到相对应的根节点位置,那根节点的左侧节点就全部都是左子树,同理右边为右子树,左子树的节点个数同先序列表中左子树的节点个数是相同的,所以也就可以把先序遍历分为三个部分,第一部分就是根节点,第二部分是左子树,个数根据中序列表可以算出,第三个是右子树;同时我们还知道先序中的三部分都是先序,中序中的三部分都是中序,那我们就可以利用这一点,不停的向下递归,产生左子树的左右孩子,右子树的左右孩子。
代码:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
#通过边界将前序遍历序列和中序遍历序列分为不同的部分
#递归方法
def build(pre_left:int,pre_right:int,in_left:int,in_right:int):
if pre_left>pre_right:
return None
#先序遍历的第一个根节点,在中序遍历中找到该根节点,根节点左侧的就是左子树,右侧的是右子树部分,然后可以用节点的个数将先序遍历的左右子树分别分开
#由例子来讲解就是先序中3是根节点,那中序中找到3,3左边的9就是左子树部分,3右边的15,20,7就是右子树的部分
#这样就把先序列表中的9和20,15,7分开,再分别用同样的方法递归3这一部分还有20,15,7这一部分了
#先找到根节点
pre_root=pre_left#先序中的第一个节点对应的就是根节点
pre_root=preorder[pre_root]#找到对应的根节点的值,等下要在中序遍历中找到对应的位置
in_root=index[pre_root]#这里的index是把中序遍历写成了一个哈希表,这样就不必每次都循环整个列表造成时间的浪费,找到了root在中序中对应的位置,然后先序列表就被分为了三部分,每一个部分都是一个先序遍历的列表
#先创建一个根节点
root=TreeNode(pre_root)
size=in_root-in_left
root.left=build(pre_left+1,pre_left+size,in_left,in_root-1)#创建左子树,并且把左子树部分的先序和中序序列再进行递归
root.right=build(pre_left+1+size,pre_right,in_root+1,in_left)
return root
#做一个中序遍历的哈希表
index={value:key for key,value in enumerate(inorder)}
n=len(preorder)
return build(0,n-1,0,n-1)
利用哈希表的目的是减少每次查询根节点在哪个位置的时间,提高效率 ,使用了enumerate函数枚举并且将键值反了过来。
题目:
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
思路:二维数组查找的题目,如果不考虑时间的问题的话可以直接使用暴力查找,但是题中给出的升序肯定是有用的,先写出暴力查找的代码,两个for循环
代码1:
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
for i in range(0,len(matrix)):
for x in range(0,len(matrix[0])):
if matrix[i][x]==target:
return True
break
return False
思路二:我们可以找一个标志位,左下角或者右上角,这里以左下角举例,用i表示某一行,j表示某一列,如果我们要查找一个数,该数比左下角的数大,那第一列肯定是不用看了,j+1,如果比左下角的数小,那最后一行不用看了,直接i-1,如果相等了,那就返回出来,循环条件是i>=0 and j<=len(matrix[0])-1,保证两个都不出界。
代码:
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
#通过标志位来写,把左下角或者右上角作为标志位
i=len(matrix)-1
j=0
while i>=0 and j<=len(matrix[0])-1:
if matrix[i][j]>target:i-=1
elif matrix[i][j]<target:j+=1
else:return True
return False