简单题二
- (leetcode 204) 求解质数个数
求解质数,使用筛法;
class Solution(object):
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
if n == 0 or n==1 or n==2:
return 0
prime = [True for i in range(n)]
for i in range(2,n):
tmp = i
if prime[tmp]:
j = 2
while tmp*j < n:
prime[tmp*j] = False
j += 1
res = 0
for i in range(2,n):
if prime[i]:
res += 1
return res
- (leetcode 206) 反转链表
很简单的一道题,但是总是不能理清next的关系;
为什么 head = head.next 与 p.next = new_head 的顺序 不饿能颠倒?
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
new_head = None
while head:
p = head
head = head.next
p.next = new_head
new_head = p
return new_head
- (leetcode 876) 寻找链表的中间节点
快慢指针貌似在链表操作中经常使用;
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
return slow
- (leetcode 234)判断一个链表是否为回文链表
需要熟悉链表的基本操作,本题涉及链表反转和找链表的中间点;
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
new_head = None
# while slow:
# p = slow.next
# slow.next = new_head
# new_head = slow
# slow = p
while slow:
p = slow
slow = slow.next
p.next = new_head
new_head = p
while new_head:
# print(new_head.val)
if new_head.val != head.val:
return False
new_head = new_head.next
head = head.next
return True
- (leetcode 237) 删除链表中的元素
刚开始一度认为题目出错了,为啥不给整个链表。看了参考才知道,,,
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
树
- (leetcode 235) 二叉搜索树的最近公共祖先
这道题审题有问题,浪费好多时间;首先,题目是二叉搜索树,是有序的,所以有更简单的做法;看输入输出的类型;
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
def findPath(root,num,tmp,path):
if not root:
return
if root.val == num.val:
path.append(tmp + [root])
return
findPath(root.left,num,tmp+[root],path)
findPath(root.right,num,tmp+[root],path)
p_path = []
q_path = []
findPath(root,p,[],p_path)
findPath(root,q,[],q_path)
p_path = p_path[0]#[::-1]
q_path = q_path[0]#[::-1]
lenm = min(len(p_path),len(q_path))
for i in range(0,lenm):
if p_path[i].val == q_path[i].val:
res = p_path[i]
return res
- (leetcode 404) 左叶子之和
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def sumOfLeftLeaves(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
res = self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right)
if root.left and not root.left.left and not root.left.right:
res += root.left.val
return res
- (leetcode 437)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
import collections
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
d = collections.defaultdict(int)
d[0] = 1
def pSum(root,cur,sum):
if not root:
return 0
res = 0
cur += root.val
if cur - sum in d:
res += d[cur-sum]
d[cur] += 1
res += pSum(root.left,cur,sum) + pSum(root.right,cur,sum)
d[cur] -= 1
return res
return pSum(root,0,sum)
感觉这种解法更容易理解
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
if not root:
return 0
return self.pSum(root,sum) + self.pathSum(root.left,sum) + self.pathSum(root.right,sum)
def pSum(self,root,sum):
ans = 0
if not root:
return ans
if root.val == sum:
ans += 1
ans += self.pSum(root.left,sum-root.val)
ans += self.pSum(root.right,sum-root.val)
return ans
- (leetcode 501) 二叉树的众数
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def findMode(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
import collections
if not root:
return []
self.dic = collections.defaultdict(int)
self.cPath(root)
maxc = max(self.dic.values())
res = []
for k,v in self.dic.items():
if v == maxc:
res.append(k)
return res
def cPath(self,root):
if not root:
return
self.dic[root.val] += 1
self.cPath(root.left)
self.cPath(root.right)
- (leetcode 538) 二叉搜索树变成累加树
这条题目思路是按照右中左的顺序计算。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def convertBST(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
self.sum = 0
def post(root):
if not root:
return
post(root.right)
self.sum += root.val
root.val = self.sum
post(root.left)
post(root)
return root
- (leetcode 543) 二叉树直径
开始有点感觉,还是有点迷糊
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def diameterOfBinaryTree(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
self.dia = 0
self.calSum(root)
return self.dia
def calSum(self,root):
if not root:
return 0
res = 1
left = self.calSum(root.left)
right = self.calSum(root.right)
self.dia = max(self.dia, left+right)
return max(left,right)+1
- (leetcode 563) 二叉树的坡度
开始有点感觉了,两个递归
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def findTilt(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
res = 0
lsum = self.calSum(root.left)
rsum = self.calSum(root.right)
return abs(lsum-rsum)+self.findTilt(root.left) + self.findTilt(root.right)
def calSum(self,root):
res = 0
if not root:
return 0
res += root.val
res += self.calSum(root.left)
res += self.calSum(root.right)
return res
- (leetcode 572) 另一颗树的子树
为啥看别人的思路一看就会,也很自然,自己就老是在里面绕圈圈。整体还是两个递归,因为需要在多个点操作,另外每个点的操作实际上是一样的。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def isSubtree(self, s, t):
"""
:type s: TreeNode
:type t: TreeNode
:rtype: bool
"""
if not s or not t:
return not s and not t
if self.judgeST(s,t):
return True
return self.isSubtree(s.left,t) or self.isSubtree(s.right,t)
def judgeST(self,s,t):
if not t or not s:
return not s and not t
if s.val != t.val:
return False
return self.judgeST(s.left,t.left) and self.judgeST(s.right,t.right)
- (leetcode 589) n叉树的前序遍历
缺少迭代版本
"""
# Definition for a Node.
class Node(object):
def __init__(self, val, children):
self.val = val
self.children = children
"""
class Solution(object):
def preorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
if not root:
return
self.path = []
self.findPath(root)
return self.path
def findPath(self,root):
self.path.append(root.val)
for v in root.children:
self.findPath(v)
return self.path
在写的过程中,本来想直接用原来的函数,不用定义新的函数,但是发现返回数组时出错。正确的更新数组的方法如下:
def preorder(self, root):
path = []
if not root:
return path
path.append(root.val)
for v in root.children:
path.extend(self.preorder(v))
return path
- (leetcode 687) 最长同值路径
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def longestUnivaluePath(self, root):
"""
:type root: TreeNode
:rtype: int
"""
self.res = 0
def calPath(root):
if not root:
return 0
# if root.val == val:
# self.res += 1
ll = calPath(root.left)
lr = calPath(root.right)
pl,pr = 0,0
if root.left and root.left.val == root.val:
pl = ll + 1
if root.right and root.right.val == root.val:
pr = lr + 1
self.res = max(self.res,pl+pr)
return max(pl, pr)
if not root:
return 0
calPath(root)
return self.res
- (leetcode 671) 二叉树中的第二小节点
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def findSecondMinimumValue(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def findMin(root):
if not root:
return float("inf")
if not root.left:
return root.val
ll = findMin(root.left)
lr = findMin(root.right)
self.la1,self.la2 = cmp([self.la1,self.la2,ll,lr,root.val])
return min(self.la1,self.la2)
def cmp(nums):
nums = list(set(nums))
nums = sorted(nums)
if len(nums) > 1:
return nums[0],nums[1]
else:
return nums[0], float("inf")
self.la1,self.la2 = float("inf"),float("inf")
findMin(root)
if self.la2 < float("inf"):
return self.la2
else:
return -1
下面这种写法更加优雅,更加优雅;只有最上面的树节点相同时才需要继续递归;
def findSecondMinimumValue(self, root):
if not root.left:
return -1
ll = self.findSecondMinimumValue(root.left) if root.left.val == root.val else root.left.val
lr = self.findSecondMinimumValue(root.right) if root.right.val == root.val else root.right.val
if ll == -1 and lr == -1:
return -1
if ll == -1:
return lr
if lr == -1:
return ll
return min(ll,lr)
- (leetcode 669) 修剪二叉搜索树
递归真的好优雅
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def trimBST(self, root, L, R):
"""
:type root: TreeNode
:type L: int
:type R: int
:rtype: TreeNode
"""
if not root:
return None
if root.val < L:
return self.trimBST(root.right,L,R)
if root.val > R:
return self.trimBST(root.left,L,R)
root.left = self.trimBST(root.left,L,R)
root.right = self.trimBST(root.right,L,R)
return root
- (leetcode 653) 寻找两数之和
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def findTarget(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: bool
"""
self.dict = {}
if not root:
return False
return self.findValue(root,k)
def findValue(self,root,val):
if not root:
return False
if val - root.val in self.dict:
return True
self.dict.setdefault(root.val,1)
return self.findValue(root.left,val) or self.findValue(root.right,val)
- (leetcode 637) 二叉树的层平均值
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
import numpy as np
class Solution(object):
def averageOfLevels(self, root):
"""
:type root: TreeNode
:rtype: List[float]
"""
res = []
if not root:
return res
cur = [root]
pre = []
tmp = []
while len(cur) > 0:
tp = cur.pop(0)
if tp.left: ## 注意添加方式
pre.append(tp.left)
if tp.right:
pre.append(tp.right)
tmp.append(tp.val)
if len(cur) == 0:
cur[:] = pre[:]
pre = []
res.append(np.mean(tmp))
tmp = []
return res
- (leetcode 993) 二叉树的堂兄弟
刚开始思路卡在如何返回值上面
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def isCousins(self, root, x, y):
"""
:type root: TreeNode
:type x: int
:type y: int
:rtype: bool
"""
def findD(root,parent,d):
if not root:
return
self.dict.setdefault(root.val,(parent,d))
findD(root.left,root,d+1)
findD(root.right,root,d+1)
self.dict = {}
findD(root,None,0)
xp,xd = self.dict[x]
yp,yd = self.dict[y]
if xp!=yp and xd == yd:
return True
return False
- (leetcode 606) 根据二叉树创建字符串
为什么自己就不能想到这么优雅的写法呢?
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def tree2str(self, t):
"""
:type t: TreeNode
:rtype: str
"""
if not t:
return ""
if not t.left and not t.right:
return str(t.val)
if not t.left:
return str(t.val) + "()" + "("+ self.tree2str(t.right) +")"
if not t.right:
return str(t.val) + "("+ self.tree2str(t.left) +")"
return str(t.val) + "(" + self.tree2str(t.left) + ")" + "(" + self.tree2str(t.right) + ")"