[LeetCode/Scala] 第144场周赛解题报告

  1. IP 地址无效化
    给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本。

所谓无效化 IP 地址,其实就是用 “[.]” 代替了每个 “.”。

示例 1:

输入:address = “1.1.1.1”
输出:“1[.]1[.]1[.]1”
示例 2:

输入:address = “255.100.50.0”
输出:“255[.]100[.]50[.]0”

提示:

给出的 address 是一个有效的 IPv4 地址


第一次看到1分的题,确实符合水平

object Solution {
    def defangIPaddr(a: String): String = {
        a.replaceAll("\\.","[.]")
    }
}
  1. 航班预订统计
    这里有 n 个航班,它们分别从 1 到 n 进行编号。

我们这儿有一份航班预订表,表中第 i 条预订记录 bookings[i] = [i, j, k] 意味着我们在从 i 到 j 的每个航班上预订了 k 个座位。

请你返回一个长度为 n 的数组 answer,按航班编号顺序返回每个航班上预订的座位数。

示例:

输入:bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5
输出:[10,55,45,25,25]

提示:

1 <= bookings.length <= 20000
1 <= bookings[i][0] <= bookings[i][1] <= n <= 20000
1 <= bookings[i][2] <= 10000


这题没过超时了, 至于为什么,我不知道,因为改成python3就AC了。 可能是OJ判断运行时间不同造成的。

object Solution {
    def corpFlightBookings(A: Array[Array[Int]], n: Int): Array[Int] = {
        val ans = Array.fill(n)(0)
        A foreach {case Array(i,j,k) =>
            ans(i-1) += k
            if(j < n) ans(j) -= k
        }
        (1 until n-1) foreach {i => ans(i) += ans(i-1)}
        ans
    }
}

给出二叉树的根节点 root,树上每个节点都有一个不同的值。

如果节点值在 to_delete 中出现,我们就把该节点从树上删去,最后得到一个森林(一些不相交的树构成的集合)。

返回森林中的每棵树。你可以按任意顺序组织答案。

示例:

输入:root = [1,2,3,4,5,6,7], to_delete = [3,5]
输出:[[1,2,null,4],[6],[7]]

提示:

树中的节点数最大为 1000。
每个节点都有一个介于 1 到 1000 之间的值,且各不相同。
to_delete.length <= 1000
to_delete 包含一些从 1 到 1000、各不相同的值。


题目说的节点最多1000个, 那就递归吧。

object Solution {
    def delNodes(root: TreeNode, to_delete: Array[Int]): List[TreeNode] = {
        var to_do = List.empty[TreeNode]
        if(root == null) Nil
        else if(to_delete.contains(root.value)) delNodes(root.left, to_delete) ++ delNodes(root.right, to_delete)
        else {
            var l = List(root)
            while(l.nonEmpty){
                val h = l.head 
                l = l.tail
                (h.left, h.right) match {
                    case (left, right) =>
                    if(left != null){
                        if(to_delete.contains(left.value)){
                            h.left = null
                            to_do ::= left
                        }
                        else l ::= left
                    }
                    if(right != null) {
                        
                        if(to_delete.contains(right.value)){
                            h.right = null
                            to_do ::= right
                        }
                        else l ::= right
                    }
                }
            }
            root::to_do.flatMap(x => delNodes(x, to_delete))
        }
    }
}

有效括号字符串 仅由 “(” 和 “)” 构成,并符合下述几个条件之一:

空字符串
连接,可以记作 AB(A 与 B 连接),其中 A 和 B 都是有效括号字符串
嵌套,可以记作 (A),其中 A 是有效括号字符串
类似地,我们可以定义任意有效括号字符串 s 的 嵌套深度 depth(S):

s 为空时,depth("") = 0
s 为 A 与 B 连接时,depth(A + B) = max(depth(A), depth(B)),其中 A 和 B 都是有效括号字符串
s 为嵌套情况,depth("(" + A + “)”) = 1 + depth(A),其中 A 是有效括号字符串
例如:"","()()",和 “()(()())” 都是有效括号字符串,嵌套深度分别为 0,1,2,而 “)(” 和 “(()” 都不是有效括号字符串。

给你一个有效括号字符串 seq,将其分成两个不相交的子序列 A 和 B,且 A 和 B 满足有效括号字符串的定义(注意:A.length + B.length = seq.length)。

现在,你需要从中选出 任意 一组有效括号字符串 A 和 B,使 max(depth(A), depth(B)) 的可能取值最小。

返回长度为 seq.length 答案数组 answer ,选择 A 还是 B 的编码规则是:如果 seq[i] 是 A 的一部分,那么 answer[i] = 0。否则,answer[i] = 1。即便有多个满足要求的答案存在,你也只需返回 一个。

示例 1:

输入:seq = “(()())”
输出:[0,1,1,1,1,0]
示例 2:

输入:seq = “()(())()”
输出:[0,0,0,1,1,0,1,1]

提示:

1 <= text.size <= 10000


如果X = (a)+(b)+©+… , 我就把每个最外的括号选了。
得到Y = (a1) + (b1) + (c1), 这时候不要选。
依次类推, 如果写成递归, 复杂度最差应该是n平方。(例子: 左括号5000,又括号5000,每次操作减少两个)。 所以不能这么做。

猜测题解应该是O(n)复杂度, 且我们处理左右括号对的问题,都是用栈的, 所以,可以推测出答案是一个堆栈程序,这也符合O(N)时间复杂度。
所以,就有了下面的算法。

  1. 遇到左括号进栈
  2. 遇到右括号,将栈顶元素弹出。做一些操作,设置是否选择标记和修改栈顶元素。

我的策略是遇到右括号,计算它的深度,如果是奇数,则设为选择。这样需要保留,内部已经计算过的括号深度。那就没办法了,必须将stack中的元素标记为新class。

这是竞赛时AC的code。

object Solution {
    case class Elem(depth:Int, idx:Int, isLeft:Boolean)
    def maxDepthAfterSplit(seq: String): Array[Int] = {
        val ans = Array.fill(seq.length)(0)
        def solve(seq:List[(Char, Int)], stack:List[Elem] = Nil):Unit = seq match {
            case Nil => {}
            case ('(', idx)::t => solve(t, Elem(0, idx, true)::stack)
            case (')', idx)::t => 
            curDepth(stack) % 2 match {
                case 0 => {}
                case 1 => 
                ans(idx) = 1
                stack.dropWhile{case Elem(x, y, bool) => !bool}.head match {
                    case Elem(_, idx2, _) => ans(idx2) = 1
                }
            }
            solve(t, f(stack))
        }
        
        def curDepth(l:List[Elem], acc:Int = 0):Int = l match {
            case Elem(depth, _, false)::t =>curDepth(t, acc max depth) 
            case Elem(_,_,true)::t => 1 + acc
        }

        def f(l:List[Elem]):List[Elem] = {
            Elem(curDepth(l), -1, false)::(l.dropWhile{case Elem(d, idx, bool) => !bool}.tail)
        }
        
        solve(seq.zipWithIndex.toList, Nil)
        ans
        
    }
}

你可能感兴趣的:(Scala,Scala,&,LeetCode)