(88,100,101,104,107,108,110,111,112,118)
88.合并两个有序数组
题目描述:
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
思路:
一般出现需要插入的方法,尾插法一般更简练。为了不移动数组,可以从后向前依次比较两个数组中的值,并且将较大的数放在最后的位置,循环完对于还没有移动的nums2的元素,整体移动过来。特殊情况:n为0时直接返回nums1,m为0时将nums2中的数字依次放进nums1中。
代码:
class Solution(object):
def merge(self, nums1, m, nums2, n):
"""
:type nums1: List[int]
:type m: int
:type nums2: List[int]
:type n: int
:rtype: None Do not return anything, modify nums1 in-place instead.
"""
len = m + n - 1
m -= 1
n -= 1
while n >= 0 and m >= 0 :
if nums1[m] >= nums2[n]:
nums1[len] = nums1[m]
m-=1;
else:
nums1[len] = nums2[n]
n-=1
len-=1
while n >= 0 :
nums1[len] = nums2[n]
n-=1
len-=1
100:相同的树
题目描述:
给定两个二叉树,编写一个函数来检验它们是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
思路:
先序遍历:判断当前两个节点的值是否相等,再递归的判断两个树的左右子树是否分别相等。
代码:
class Solution(object):
def isSameTree(self, p, q):
"""
:type p: TreeNode
:type q: TreeNode
:rtype: bool
"""
if not p and not q:
return True
elif p and q and p.val==q.val:
return self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
else:
return False
101:对称二叉树
题目描述:
给定一个二叉树,检查它是否是镜像对称的。
思路:
1:如果是对称二叉树,则每一层都应该是对称的,因此可以通过层次遍历,判断每一层是不是对称
2:递归求解,它们的两个根结点具有相同的值。每个树的右子树都与另一个树的左子树镜像对称。
代码:
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
lq=[root.left]
rq=[root.right]
while lq and rq:
l=lq.pop(0)
r=rq.pop(0)
if not l and not r:
continue
elif not l or not r:
return False
elif l.val!=r.val:
return False
lq.extend([l.left,l.right])
rq.extend([r.right,r.left])
return True
104:二叉树的最大深度
题目描述:
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
思路:
当前树的最大深度=Max(左子树的最大深度,右子树的最大深度)+1
代码:
class Solution(object):
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
elif not root.left and not root.right:
return 1
else:
left=self.maxDepth(root.left)
right=self.maxDepth(root.right)
depth=max(left,right)+1
return depth
107:二叉树的层次遍历
题目描述:
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
思路:
每遍历一个节点就把该节点的左孩子和右孩子放进队列,遍历完这个节点之后就从队列中取出头节点(取出的节点有可能是右边的同层节点,也有可能是下一层的第一个节点),然后直到遍历完成。
逐层遍历,每一层存入到数组中,等下一次遍历。将该层的值存到数组,并将下一层的节点存入list。将此层添加到列表头。
代码:
class Solution(object):
def levelOrderBottom(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if root==None:
return []
queue=[root]
result=[]
while len(queue)>0:
childqueue=[]
tem=[]
for i in queue:
childqueue.append(i.val)
if i.left!=None:
tem.append(i.left)
if i.right!=None:
tem.append(i.right)
queue=tem
result.insert(0,childqueue)
return result
108:将有序数组转换为二叉搜索树
题目描述:
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
思路:
二分查找中间值,递归解决。获取列表的中间元素,利用二分法每次递归的将数组分别分为两部分,其中每次中间节点为根元素,左边为左子树,右边为右子树
代码:
class Solution(object):
def sortedArrayToBST(self, nums):
"""
:type nums: List[int]
:rtype: TreeNode
"""
if not nums:
return None
mid=len(nums)//2
ltree=nums[:mid]
rtree=nums[mid+1:]
tree=TreeNode(nums[mid])
tree.val=nums[mid]
tree.left=self.sortedArrayToBST(ltree)
tree.right=self.sortedArrayToBST(rtree)
return tree
110:平衡二叉树
题目描述:
给定一个二叉树,判断它是否是高度平衡的二叉树。一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
思路:
左子树是平衡树,右子树也是平衡树并且深度差值不超过1
优化:第二层的自顶向下的必须全部遍历完,这是无法避免的,但每次节点时的求maxDepth操作却可以减少,原因是maxDepth是自底向上的后序遍历,可以提前截断,当底层的子树不满足平衡树时,直接向上传递此树不是平衡树的信息(即返回子树深度为-1),而不是传递当前树的深度,这样可以不用做很多不必要的操作。
代码:
class Solution(object):
def isBalanced(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
else:
a=self.maxDepth(root.left)
b=self.maxDepth(root.right)
if abs(a-b)<=1 and self.isBalanced(root.left) and self.isBalanced(root.right):
return True
else:
return False
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
else:
left=self.maxDepth(root.left)
right=self.maxDepth(root.right)
depth=max(left,right)+1
return depth
111.二叉树的最小深度
题目描述:
给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
思路:
求最小深度时将max换成min即可,但要注意如果根节点的左或右子树为空的话是构不成子树的。而最小深度是要求从根节点到子树的。当左或右子树为空时,不符合要求。如果有一个子树没有任何节点,那么最小值是另一棵树的深度。
代码:
class Solution(object):
def minDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
elif not root.left and not root.right:
return 1
elif not root.left and root.right:
return self.minDepth(root.right)+1
elif not root.right and root.left:
return self.minDepth(root.left)+1
else:
return min(self.minDepth(root.left),self.minDepth(root.right))+1
112:路径总和
题目描述:
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
思路:
利用递归,遍历整棵树:如果当前节点不是叶子,对它的所有孩子节点,递归调用 hasPathSum 函数,其中 sum 值减去当前节点的权值;如果当前节点是叶子,检查 sum 值是否为 0,也就是是否找到了给定的目标和。
代码:
class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if not root:
return False
elif not root.left and not root.right:
s=root.val-sum
if s==0:
return True
else:
return False
else:
sum1=root.val
return self.hasPathSum(root.left,sum-sum1) or self.hasPathSum(root.right,sum-sum1)
118:杨辉三角
题目描述:
给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
思路:
先为当前行生成空列表并将首尾设为1
再利用动态规划基于上一行生成当前行
每个子数组的长度为当前行数,每个子数组里的值为它左上方和右上方的数的和
代码:
class Solution(object):
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
numRows=int(numRows)
yh=[[1],[1,1]]
if numRows==0:
return []
elif numRows==1:
return yh[:-1]
elif numRows==2:
return yh
else:
for i in range(2,numRows):
yh1=[1]
for j in range(0,len(yh[-1])-1):
add1=yh[-1][j]+yh[-1][j+1]
yh1.append(add1)
yh1.append(1)
yh.append(yh1)
return yh