简单题 二

简单题二

  1. (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
  1. (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
  1. (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
  1. (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
  1. (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

  1. (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
  1. (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
  1. (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
  1. (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)
  1. (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
  1. (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
  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
  1. (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)
  1. (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
  1. (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
  1. (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)
  1. (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
  1. (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)
  1. (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
  1. (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
  1. (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) + ")" 
posted @ 2019-04-15 00:52  静_渊  阅读(201)  评论(0编辑  收藏  举报