【周赛】第131场-2019-4-7

目录

1. 栈。删除最外层括号

2. 树。从根到叶的二进制数之和

3. 字符串。驼峰式匹配

4. DP。视频拼接


 

1. 栈。删除最外层括号

  • 题目描述:有效括号字符串为空 ("")、"(" + A + ")" 或 A + B,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。例如,"","()","(())()" 和 "(()(()))" 都是有效的括号字符串。如果有效字符串 S 非空,且不存在将其拆分为 S = A+B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。给出一个非空有效字符串 S,考虑将其进行原语化分解,使得:S = P_1 + P_2 + ... + P_k,其中 P_i 是有效括号字符串原语。对 S 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 S 。
输入:"(()())(())"
输出:"()()()"
解释:输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())",删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"。

 

  •  解法。找到原语(左括号等于右括号数),然后对原语剥掉最外层。用2个栈,res是存储截至目前的结果,st是辅助栈存储当前原语的结果。变量balanced记录当前左右括号数是否平衡,通过balanced是否为0判断当前是处于首尾还是中间,若是非首尾就要放到st里,然后一旦原语遍历结束了就把st的内容取出来再清空
  • ​class Solution:
        def removeOuterParentheses(self, S: str) -> str:
            if not S:
                return ""
            st = []
            i = 0
            balanced = 0
            res = []
            while i < len(S):
                if S[i] == '(':
                    if balanced != 0:
                        st.append(S[i])
                    balanced += 1
                elif S[i] == ')':
                    balanced -= 1
                    if balanced != 0:
                        st.append(S[i])
                    else:
                        res += st
                        st = []
                i += 1
            return ''.join(res)
    
    ​

     

2. 树。从根到叶的二进制数之和

  • 题目描述:给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。以 10^9 + 7 为模,返回这些数字之和。
输入:[1,0,1,0,1,0,1]
输出:22
解释:(100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22

 

  •  解法。DFS的方式存储下从根节点到叶子结点的二进制数对应的十进制值,注意可以一边递归一边计算
  • class Solution:
        def sumRootToLeaf(self, root: TreeNode) -> int:
            if not root:
                return 0
            res = []
            self.helper(root, 0, res)
            return sum(res) if sum(res) < 2**31 else 2**31-1
        
        def helper(self, root, cur, res):
            if not root:
                return
            if not root.left and not root.right:
                res.append(cur*2+root.val)
                return
            self.helper(root.left, cur*2+root.val, res)
            self.helper(root.right, cur*2+root.val, res)
            return

3. 字符串。驼峰式匹配

  • 题目描述:如果我们可以将小写字母插入模式串 pattern 得到待查询项 query,那么待查询项与给定模式串匹配。(我们可以在任何位置插入每个字符,也可以插入 0 个字符。)给定待查询列表 queries,和模式串 pattern,返回由布尔值组成的答案列表 answer。只有在待查项 queries[i] 与模式串 pattern 匹配时, answer[i] 才为 true,否则为 false。

输出:queries = ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern = "FoBaT"

输入:[false,true,false,false,false]

解释: "FooBarTest" 可以这样生成:"Fo" + "o" + "Ba" + "r" + "T" + "est".

  •   解法。对于被匹配的queries,匹配两者相等的字母,剩余的跳过即可。匹配完毕可能是queries先匹配完,也可能是pattern先匹配完,分清楚情况
class Solution:
    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:
        if not queries or not pattern:
            return []
        res = []
        for q in queries:
            if self.match(q, pattern):
                res.append(True)
            else:
                res.append(False)
        return res
    
    def match(self, que, patt):
        if not que:
            return False
        i, j = 0, 0
        while i < len(que) and j < len(patt):
            if que[i] == patt[j]:
                i += 1
                j += 1
                continue
            else:
                if 'A' <= que[i] <= 'Z':
                    return False
                i += 1
        while i < len(que):
            if 'A' <= que[i] <= 'Z':
                return False
            i += 1
        if j == len(patt):
            return True
        else:
            return False

 

4. DP。视频拼接

  • 题目描述:你将会获得一系列视频片段,这些片段来自于一项持续时长为 T 秒的体育赛事。这些片段可能有所重叠,也可能长度不一。视频片段 clips[i] 都用区间进行表示:开始于 clips[i][0] 并于 clips[i][1] 结束。我们甚至可以对这些片段自由地再剪辑,例如片段 [0, 7] 可以剪切成 [0, 1] + [1, 3] + [3, 7] 三部分。我们需要将这些片段进行再剪辑,并将剪辑后的内容拼接成覆盖整个运动过程的片段([0, T])。返回所需片段的最小数目,如果无法完成该任务,则返回 -1 。
输入:clips = [[0,1],[6,8],[0,2],[5,6],[0,4],[0,3],[6,7],[1,3],[4,7],[1,4],[2,5],[2,6],[3,4],[4,5],[5,7],[6,9]], T = 9
输出:3
解释: 我们选取片段 [0,4], [4,7] 和 [6,9] 。
  • 解法。
    • 解法1,可以从图搜的角度理解,确定好起点,然后遍历找最短路径
    • 解法2,贪心的角度,这里贪心的思想不是体现在每次吞并能吞并的(只要能拓展范围),而是把能辐射到的范围看为1个组里的(就是内层while循环遍历过的都属于一个组),最终res记录的其实就是有几个组,并且每次取的都是组内的最优范围
  • # 解法1
    class Solution:
        def videoStitching(self, clips: List[List[int]], T: int) -> int:
            if not clips:
                return -1
            n = len(clips)
            # 必须要这么排才能找到最短路径
            clips.sort(key = lambda x: (x[0], -x[1]))
            if clips[0][0] > 0:
                return -1
            visited = [False for _ in range(n)]
            visited[0] = True
            q = [(clips[0], 1)]
            while q:
                cur, level = q.pop(0)
                if cur[0] <= 0 and cur[1] >= T:
                    return level
                # 因为取了clips[0]作为起点,所以此处就从1开始
                for i in range(1, len(clips)):
                    if not visited[i]:
                        if clips[i][0] >= cur[0] and clips[i][1] <= cur[1]:
                            visited[i] = True
                            continue
                        elif clips[i][0] <= cur[1]:
                            visited[i] = True
                            # 此处的剪枝可以略去,无妨
                            # if q and max(cur[1], clips[i][1]) >= q[0][0][1]:
                            #     q.pop(0)
                            q.append(([min(cur[0], clips[i][0]), max(cur[1], clips[i][1])], level+1))
            return -1
  • # 解法2
    class Solution:
        def videoStitching(self, clips: List[List[int]], T: int) -> int:
            if not clips or T <= 0:
                return 0
            # 这里排序可以是双升序,也可以是x[0]升序x[1]降序
            clips.sort()
            res = 0
            cur_end, max_end = 0, 0
            i = 0
            n = len(clips)
            while i < n:
                if clips[i][0] > cur_end:
                    return -1
                max_end = cur_end
                while i < n and clips[i][0] <= cur_end:
                    if clips[i][1] > max_end:
                        max_end = clips[i][1]
                    i += 1
                res += 1
                cur_end = max_end
                if cur_end >= T:
                    return res
            return -1

     

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值