Leetcode刷题记录本
ID: 1
- 暴力破解法
点击查看代码
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
# 暴力破解法
for i in range(len(nums)):
for j in range(len(nums)):
if nums[i]+nums[j]==target:
return [i,j]
- 使用字典,即key-map
点击查看代码
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
records = dict()
# 字典以key-value的形式存储 实际的值和它对应的下标
for index,value in enumerate(nums):
if target-value in records:
return [records[target-value],index]
records[value] = index
ID: 704
点击查看代码
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left, right = 0,len(nums)-1
while left<=right:
mid = (left+right)//2
if nums[mid]<target:
left = mid+1
elif nums[mid]>target:
right = mid-1
else:
return mid
return -1
ID: 27
点击查看代码
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
fast=slow=0
n = len(nums)
for fast, value in enumerate(nums):
if nums[fast]!=val:
nums[slow] = nums[fast]
slow+=1
return slow
ID: 977
点击查看代码
class Solution(object):
def sortedSquares(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
#定义左右指针
left, right = 0,len(nums)-1
# 定义结果集
res = [0]*len(nums)
#定义结果集下标
k=len(nums)-1
# 最大值要么出现在最左端或者最右端,两个指针相向而行
for index, value in enumerate(nums):
if nums[left]*nums[left]<nums[right]*nums[right]:
res[k] = nums[right]*nums[right]
right-=1
else:
res[k] = nums[left]*nums[left]
left+=1
k-=1
return res
ID: 209
点击查看代码
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
# 利用滑动窗口
start = 0 #起始指针
sum_ = 0 # 用于求和
min_len = 0
for end, value in enumerate(nums):
sum_+=nums[end]
while sum_ >= target: #满足条件后的窗口大小
sub_len = end-start+1
if min_len==0:
min_len = sub_len
else:
min_len = min(min_len,sub_len)
sum_-=nums[start] #缩减窗口
start+=1
return min_len
ID: 203
点击查看代码
class Solution(object):
def removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
# 设置虚拟头结点 再进行统一的移除节点操作
dymmy_node = ListNode(next = head)
# 用于遍历的临时指针cur(直接操作头结点,值会被修改,后面无法return头结点的值)
cur = dymmy_node
while cur.next!= None: #当前节点的下一个节点不为空
if cur.next.val==val:
cur.next = cur.next.next # 将cur->next设置为cur->next->next并删除cur->next
else:
cur = cur.next
return dymmy_node.next
ID: 207
点击查看代码
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 双指针法
cur = head #指向当前节点
pre = None #指点前驱节点
while cur!=None:
tmp = cur.next #把后继结点先存储起来
cur.next = pre #把指针指向pre
pre = cur #把当前节点反转为前驱节点
cur = tmp #移动工作指针
return pre
ID: 242
点击查看代码
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
# 定义一个数组,长度为26
# 遍历s,把res对应位置的数值加1
# 再遍历t,把res对应的位置数值减1
# 最后结果如果都是0,则说明是;
# ord是将字符转换为数值
res = [0]*26
for index,value in enumerate(s):
res[ord(value)-ord('a')]+=1
for index,value in enumerate(t):
res[ord(value)-ord('a')]-=1
for index,value in enumerate(res):
if value != 0:
return False
return True
ID: 349
点击查看代码
class Solution(object):
def intersection(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
res = list(set(nums1)&set(nums2))
return res
ID: 349
- 利用python的set存储每次的数字,如果陷入循环了,直接返回false
点击查看代码
class Solution(object):
def isHappy(self, n):
"""
:type n: int
:rtype: bool
"""
res = set()
while n!= 1:
sum_ = 0
if n in res:
return False
res.add(n)
# 取n的每一位数字
for num in str(n):
sum_+=int(num)**2
n = sum_
return True
ID: 383
- 这道题和242题很像,都用一个26长度的数组存储字符
点击查看代码
class Solution(object):
def canConstruct(self, ransomNote, magazine):
"""
:type ransomNote: str
:type magazine: str
:rtype: bool
"""
# 这题和242的字母异位词的题类似
res = [0]*26
for index,value in enumerate(magazine):
res[ord(value)-ord('a')]+=1
for index,value in enumerate(ransomNote):
#如果ransomNote出现的字符在magazine没有,则直接返回false
if res[ord(value)-ord('a')]==0:
return False
# 这一步的-1不要忘了,因为value只能使用一次,不能重复使用
else:
res[ord(value)-ord('a')]-=1
return True
ID: 344
点击查看代码
class Solution(object):
def reverseString(self, s):
"""
:type s: List[str]
:rtype: None Do not return anything, modify s in-place instead.
"""
#左右指针法
left, right = 0, len(s)-1
# 这里的判定条件得写好! 不能用mid,也不要用!=
while(left<=right):
s[left] , s[right] = s[right], s[left]
left+=1
right-=1
return s
ID: 144
- 二叉树的前序遍历,使用递归,函数里定义出口、在函数里递归;
点击查看代码
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def pre_order(root):
if root==None:
return
res.append(root.val)
pre_order(root.left)
pre_order(root.right)
#来个入口函数,调用一次
pre_order(root)
return res
- 使用迭代法(循环法),需要借助到栈
点击查看代码
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
if root==None:
return res
stack = [root]
while stack:
node = stack.pop()
res.append(node.val)
#利用栈先进后出的特点,确保先把右子树压入栈,这样子左子树一定先出来
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
ID: 145
- 二叉树的后序遍历,使用递归,函数里定义出口、在函数里递归;最后入口调用不要忘了
点击查看代码
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
#跟前序一样,自己实现一遍
res = []
#使用递归法
def post_order(root):
if root==None:
return
post_order(root.left)
post_order(root.right)
res.append(root.val)
post_order(root)
return res
- 使用迭代法(循环法),需要借助到栈;前序:根-左-后,先调换 根-右-左,再逆序输出,左-右-根
点击查看代码
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
#跟前序一样,自己实现一遍
res = []
#使用栈来实现
# 跟前序差不多,只不过需要调换顺序:
# 前序:根-左-后,先调换 根-右-左,再逆序输出,左-右-根
stack = [root]
while stack:
node = stack.pop()
res.append(node.val)
#先把左子树压入栈,确保顺序是 右-左
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
## list[::-1]表示列表逆序输出,python的特性,可以用
return res[::-1]
ID: 99
- 二叉树的中序遍历,使用递归,函数里定义出口、在函数里递归;最后入口调用不要忘了
点击查看代码
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def in_order(root):
if root==None:
return
in_order(root.left)
res.append(root.val)
in_order(root.right)
in_order(root)
return res
- 使用迭代法(循环法),需要借助到栈;不能像上面一样做了,需要一个工作指针,这道题值得做第二遍
点击查看代码
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
stack = []
cur = root #不能像上面一样做了,需要一个工作指针
while cur or stack:
if cur:
stack.append(cur) #这一行不仅只针对左子树,工作指针用于指向当前的树
cur = cur.left
else:
node = stack.pop()
res.append(node.val)
if node.right:
cur = node.right
return res
ID: 102
- 二叉树的层序遍历,使用递归
点击查看代码
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
res = []
def level_order(root,depth):
# 出口条件
if root==None:
return
# 添加层数
if len(res)==depth:
res.append([])
#深搜,对于每一个深度,即每一层设置值
res[depth].append(root.val)
level_order(root.left,depth+1)
level_order(root.right,depth+1)
level_order(root,0)
return res
ID: 107
- 二叉树的逆序层序遍历,使用递归;相较上一题,直接先正着层序遍历,再把结果数组翻一下。
点击查看代码
class Solution(object):
def levelOrderBottom(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
res = []
def level_order(root,depth):
if root==None:
return
if len(res)==depth:
res.append([])
res[depth].append(root.val)
level_order(root.left,depth+1)
level_order(root.right,depth+1)
level_order(root,0)
return res[::-1]
ID: 199
- 二叉树的右视图,使用队列来实现,判断最每一层最右边的结点。
点击查看代码
class Solution(object):
def rightSideView(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
# 每一层的最右边的那个结点即是答案,判断每一层是否是最右边的结点
res = []
#使用队列来实现
from collections import deque
if root==None:
return []
que = deque([root])
while que:
# 每次都取最后一个结点,这里不用pop的原因是pop会删除最后一个元素
node = que[-1]
res.append(node.val)
# 遍历获取每一层的所有node
for _ in range(len(que)):
node = que.popleft()
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return res
ID: 637
- 二叉树的每一层的平均数。
点击查看代码
class Solution(object):
def averageOfLevels(self, root):
"""
:type root: TreeNode
:rtype: List[float]
"""
res = []
final_res = []
def level_order(root,depth):
if root==None:
return
if len(res) == depth:
res.append([])
res[depth].append(root.val)
if root.left:
level_order(root.left,depth+1)
if root.right:
level_order(root.right,depth+1)
level_order(root,0)
for index,value in enumerate(res):
avg = sum(value)*1.0/len(value)
final_res.append(avg)
return final_res
ID: 429
- N叉树的层序遍历。
点击查看代码
class Solution(object):
def levelOrder(self, root):
"""
:type root: Node
:rtype: List[List[int]]
"""
final_res = []
from collections import deque
que = deque([root])
while que:
res = []
# 这里还有一个循环
for _ in range(len(que)):
cur = que.popleft()
res.append(cur.val)
if cur.children:
#注意这里是extend()
que.extend(cur.children)
final_res.append(res)
return final_res
ID: 515
- 在每个树行中找最大值,没什么好说的,跟前面的一样。
点击查看代码
class Solution(object):
def largestValues(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
final_res = []
def level_order(root,depth):
if root==None:
return
if len(res) == depth:
res.append([])
res[depth].append(root.val)
if root.left:
level_order(root.left,depth+1)
if root.right:
level_order(root.right,depth+1)
level_order(root,0)
for index,value in enumerate(res):
max_ = max(value)
final_res.append(max_)
return final_res
ID: 513
- 找树的最下层的最左边的元素,注意这里的坑是它没说是完全二叉树,所以那个元素不一定就出现在最最左边,所以不能用深度递归。
点击查看代码
class Solution(object):
def findBottomLeftValue(self, root):
"""
:type root: TreeNode
:rtype: int
"""
target = 0
from collections import deque
que = deque([root])
while que:
for i in range(len(que)):
cur = que.popleft()
# 判断每一层的第一个元素
if i ==0:
target=cur.val
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
return target
ID: 116
- 填充每个节点的下一个右侧节点指针。
解题思路:在层序遍历时,记录本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了。
点击查看代码
class Solution(object):
def connect(self, root):
"""
:type root: Node
:rtype: Node
"""
from collections import deque
que = deque([root])
while que:
size = len(que)
#单层遍历
for i in range(size):
cur = que.popleft()
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
# 这里需要终止掉,因为最后要确保每一层的que里至少有两个元素
if i==size-1:
break
cur.next = que[0]
return root
ID: 117
- 填充每个节点的下一个右侧节点指针。
解题思路:设置一个指针用于记录上一个结点,这题的答案可以适用于ID: 116
点击查看代码
class Solution(object):
def connect(self, root):
"""
:type root: Node
:rtype: Node
"""
#开头不要忘了判断空值
if root==None:
return
from collections import deque
que = deque([root])
while que:
size = len(que)
#设置一个指针用于记录上一个结点
tail = None
#单层遍历
for i in range(size):
cur = que.popleft()
# 此后都让上一个指针指向当前指针
if tail:
tail.next = cur
#初始的时候将工作指针赋给tail
tail = cur
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
return root
ID: 104
- 二叉树的最大深度,层序遍历的题,没啥好说的。
点击查看代码
class Solution(object):
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
res = []
def level_order(root,depth):
if root==None:
return
if len(res) == depth:
res.append([])
res[depth].append(root.val)
if root.left:
level_order(root.left,depth+1)
if root.right:
level_order(root.right,depth+1)
level_order(root,0)
return len(res)
ID: 111
- 二叉树的最小深度
点击查看代码
class Solution(object):
def minDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if root==None:
return 0
from collections import deque
# que里面存储的是一个tuple,再外面套一个列表,标准格式
que = deque([(root,1)])
while que:
size = len(que)
for i in range(size):
#取的时候也是这么取
node,depth = que.popleft()
if node.left==None and node.right==None:
return depth
if node.left:
que.append((node.left,depth+1))
if node.right:
que.append((node.right,depth+1))
return 0
ID: 226
- 翻转二叉树
点击查看代码
class Solution(object):
def invertTree(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
# 层序遍历,,把每个节点的左右孩子都翻转一遍
if root==None:
return
from collections import deque
que = deque([root])
while que:
node = que.popleft()
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
# 不只是调换值,还需要调换整个分支,因此不能简单地用.val
if node.left and node.right:
node.left, node.right = node.right, node.left
return root