题34:二叉树中和为某一值的路径
深度优先能想到,但还是有几个点是自己没想清楚的:
- 关于target匹配,我想的是从0开始,加上当前节点的值,去判断是否和target相等,但大佬的做法是从target开始,减去当前节点的值,判断是否为0;这一做法的好处是,避免了回朔过程中的当前值难以记录的问题,妙啊
- 关于将list的append问题,由于path指向列表,因此直接用
res.append(path)
是将path指向的空间加到了res里,后续path改变时,res也会变(深浅拷贝问题),解决方法是,采用res.append(list(path)
,这样相当于创建了一个新的列表,将其加到了res里,妙啊 - 关于path在哪里pop问题,嗯……很妙!
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def pathSum(self, root: TreeNode, target: int) -> List[List[int]]:
res = []
def dfs(root:TreeNode,cum:int,path:List[int]):
if root!=None:
path.append(root.val)
cum-=root.val
if cum == 0 and root.left==None and root.right==None:
res.append(list(path))
else:
dfs(root.left,cum,path)
dfs(root.right,cum,path)
path.pop()
dfs(root,target,[])
return res
题35:复杂链表的复制
自己想的:一共两次遍历,
- 第一次遍历用于创造出新的链表,构建next关系,同时,将新旧链表的每个节点都放到各自的list中(目的是使其可通过下标寻找)
- 第二次遍历则利用
list.index
函数找到下标,将其对应
可能并不是最优解,但还是自己想出来的,鼓励一下👏
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if head==None:
return None
newhead=Node(head.val)
old,new=head,newhead
oldlist,newlist=[],[]
while old!=None:
oldlist.append(old)
newlist.append(new)
if old.next!=None:
tmp=Node(old.next.val)
new.next=tmp
else:
new.next=None
old,new=old.next,new.next
old,new=head,newhead
while old!=None:
if old.random!=None:
ind=oldlist.index(old.random)
new.random=newlist[ind]
else:
new.random=None
old,new=old.next,new.next
return newhead
题36:二叉搜索树与双向链表
法一:比较暴力,中序遍历一遍把节点存在list中,然后遍历一遍list,构造引用关系
"""
# Definition for a Node.
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
"""
class Solution:
def treeToDoublyList(self, root: 'Node') -> 'Node':
if root==None:
return None
nodelist = []
def inorder(root:'Node'):
if root!=None:
inorder(root.left)
nodelist.append(root)
inorder(root.right)
inorder(root)
for i in range(len(nodelist)):
if i!=len(nodelist)-1 and i!=0:
nodelist[i].left=nodelist[i-1]
nodelist[i].right=nodelist[i+1]
elif i==len(nodelist)-1:
nodelist[i].left=nodelist[i-1]
nodelist[i].right=nodelist[0]
else:
nodelist[i].left=nodelist[-1]
nodelist[i].right=nodelist[i+1]
return nodelist[0]
法二:画一画图可以发现,只需要调整节点的指向即可->cur.left,pre.right=pre,cur
几个细节:
1、head节点的记录
2、当dfs运行完后,此时的pre就是最后一个节点!!
"""
# Definition for a Node.
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
"""
class Solution:
def treeToDoublyList(self, root: 'Node') -> 'Node':
if not root:return
pre,head=None,None
def dfs(cur:"Node"):
nonlocal pre,head
if not cur: return
dfs(cur.left)
if pre:
pre.right,cur.left=cur,pre
else:
head=cur
pre=cur
dfs(cur.right)
dfs(root)
head.left,pre.right=pre,head
return head
题37:序列化二叉树
序列化还好做,利用队列即可,但是反序列化是第一次,本想用二叉树的性质(第i个节点的左节点处于2i处,右节点处于2i+1处,但这样遇到null时很难处理,参考了大佬的题解,发现反序列化也可以用队列,代码如下:
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
if root==None:
return '[]'
queue,res=[root],'['
while len(queue)!=0:
tmp=queue.pop(0)
if tmp!=None:
res+=str(tmp.val)+','
queue.append(tmp.left)
queue.append(tmp.right)
else:
res+=('null,')
res=res[:-1]+']'
return res
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
if data=='[]':
return None
data=data[1:-1].split(',')
rt=TreeNode(int(data[0]))
queue,ind=[rt],1
while len(queue)!=0:
root=queue.pop(0)
if data[ind]!='null':
root.left=TreeNode(int(data[ind]))
queue.append(root.left)
ind+=1
if data[ind]!='null':
root.right=TreeNode(int(data[ind]))
queue.append(root.right)
ind+=1
return rt
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))