12月6日 331,332, 334, 337, 343,347

12月以来有点忙,而目测得忙到12月中,之间抽空写了几道,计算天数已经没什么意义了,就这样吧。

本来打算先到200的时候,暂缓一段时间,等忙完再开始,现在是197道,但是题号已经到300多了……中间锁住的还有很多SQL相关的。

331. Verify Preorder Serialization of a Binary Tree

对于一棵树来说,我们可以用前序遍历来写出它的所有元素,对于空值我们用#来表示,现在给定一个前序的顺序,判断能不能组成一棵树。

在这里插入图片描述
像上图中的例子,我们就可以表示为[9,3,4,#,#,1,#,#,2,#,6,#,#]

关于这题,我们可以用栈的想法去做。

以上面的二叉树为例:

我们定义一个栈,stack = []

然后开始遍历前序顺序,把元素不断的压入栈

[9,3,4,#],这时候要压入的元素是#,栈顶的也是#,我们弹出前面的两个元素,然后再压入一个#。这就相当于将原来的一个二叉树子树用#代替了,然后我们栈内的元素为[9,3,#]
按照这个规则然后继续[9,3,#,1] → \to [9,3,#,1,#] → \to [9,3,#,#] → \to [9,#] → \to [9,#,2] → \to [9,#,2,#] → \to [9,#,2,#,6] → \to [9,#,2,#,5,#] → \to [9,#,2,#,#] → \to [9,#,#] → \to [#]

而且剩下的是[#],而且这时候前序顺序也遍历完毕,如果[#]出现在前面的话,那么就说明这个序列不正确,或者最后剩下的不是[#]

那么再次仔细观察我们的序列,其实我们真正关心的不是序列内的值,而是序列内#的个数以及非#的个数,当遇到#的时候-1,遇到普通数字的时候+1#的数量比数字的个数要多一个,因此如果初始值是1的话,最后应该是0,而且中间不能出现0,也就是对应上面[#]的情况。

所以我们最后的代码为:

class Solution(object):
    def isValidSerialization(self, preorder):
        """
        :type preorder: str
        :rtype: bool
        """
        nodes = preorder.split(',')
        num = 1
        for node in predorder:
            if node == '#':
                num-=1
            else:
                num+=1
                if num ==1:
                    return False
        return num==0

332. Reconstruct Itinerary

给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序。所有这些机票都属于一个从JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 出发。

说明:

如果存在多种有效的行程,你可以按字符自然排序返回最小的行程组合。例如,行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小,排序更靠前
所有的机场都用三个大写字母表示(机场代码)。
假定所有机票至少存在一种合理的行程。

示例 1:

输入: [[“MUC”, “LHR”], [“JFK”, “MUC”], [“SFO”, “SJC”], [“LHR”, “SFO”]]
输出: [“JFK”, “MUC”, “LHR”, “SFO”, “SJC”]

示例 2:

输入: [[“JFK”,“SFO”],[“JFK”,“ATL”],[“SFO”,“ATL”],[“ATL”,“JFK”],[“ATL”,“SFO”]]
输出: [“JFK”,“ATL”,“JFK”,“SFO”,“ATL”,“SFO”]
解释: 另一种有效的行程是 [“JFK”,“SFO”,“ATL”,“JFK”,“ATL”,“SFO”]。但是它自然排序更大更靠后。

中文题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reconstruct-itinerary

这里需要强调的有几点,而搞明白其中的这几点对于我们做出这道题有着很大的帮助。

  • 其中出现奇数次的机场肯定是起点(JFK)或者是终点
  • 如果没有奇数点,此时起点和终点是一个点,此时可以顺利的从从起点到终点走完。
  • 我们可能会提前遇到终点从而出现阻塞。

因此,堵塞的时候,就是遇到终点的时候,我们将到终点的这条路径储存到route中,然后往前回溯寻找下一个条路。

代码

class Solution(object):
    def findItinerary(self, tickets):
        """
        :type tickets: List[List[str]]
        :rtype: List[str]
        """
        
        dict_travel = {}
        for s,a in sorted(tickets)[::-1]:
            dict_travel[s] = dict_travel.get(s, [])+[a] 
        route, stack = [],['JFK']
        while stack:
            while dict_travel.has_key(stack[-1]) and dict_travel[stack[-1]]:
                stack.append(dict_travel[stack[-1]].pop())
            route.append(stack.pop())
        return route[::-1]

334. Increasing Triplet Subsequence

判断一个数列中有没有递增的三个数。
很简单,我们存下最小的和最大的数 ,判断没有有比他们更大的就行了。

代码如下:

class Solution(object):
    def increasingTriplet(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        first = second = float('inf')
        for i in nums:
            if i <= first:
                first = i
            elif i <= second:
                second = i
            else:
                return True
        return False

337. House Robber III

解法可以看这里

这是我在Leetcode上暂时见过最好的回答。

代码如下:

# 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 rob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        res = self.subrob(root)
        return max(res)
    def subrob(self, root):
        
        if not root:
            return [0,0]
        
        left = self.subrob(root.left)
        right = self.subrob(root.right)
        res = [0, 0]
        res[1] = root.val + left[0] + right[0]
        res[0] = max(left[0], left[1]) + max(right[0], right[1])
        
        return res

343. Integer Break

将一个数拆成至少两个正整数,求这几个正整数的最大乘积。

其实只要拆成2和3就就可以了。4=2*2,5<3*2

代码如下:

class Solution(object):
    def integerBreak(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n<=3:
            return n-1
        if n%3==0:
            return pow(3, n//3)
        if n%3==1:
            return pow(3, n//3-1)*4
        if n%3==2:
            return pow(3,n//3)*2

347. Top K Frequent Elements

返回一个数列出现次数在第k多以前的数。

用哈希表的话就很简单了。

class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        dic = {}
        
        for i in nums:
            dic[i] = dic.get(i,0)+1
            
        arr = sorted(dic, key = dic.get)[::-1]
        
        return arr[:k]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值