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

本文解析了四道编程题的解决方案,包括寻找最优构造方法、游戏策略分析、利用Hash实现快照数组和贪心算法进行字符串分解。通过实际代码展示了不同问题的解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

P1:按题意有两种构造方法,只需要比较哪种代价更小就可以了。

object Solution {
    def movesToMakeZigzag(A: Array[Int]): Int = {
        def f(i:Int):Int = {
            A.indices.toList
            .filter(_%2 == i)
            .map{x =>
                0 max (List(x-1, x+1) filter A.indices.contains map A map (y => A(x) - y + 1) max)}
            .sum
      }
        f(0) min f(1)
    }
}

P2: 在选手一选完之后, 选手二只能有三种选择方式:记选手选择xxx, 选手二的选择,只能是x的父节点,左节点,或者右节点。 这样做能让压缩选手一的最后结果。 所以,只要比较这三种的最大值是否存在一个值比整棵树的一半大即可。

object Solution {
    def btreeGameWinningMove(root: TreeNode, n: Int, x: Int): Boolean = find(root,x) match {
        case node => 
        (count(node), count(node.left), count(node.right)) match {
            case (m, m_l, m_r) => List(n-m, m_l, m_r).max > n /2 
        }
    }
    def count(root:TreeNode):Int = root match {
        case null => 0
        case _ => count(root.left) + count(root.right) + 1
    }
    
    def find(root:TreeNode, x:Int):TreeNode = {
        if(root == null)  null
        else if(root.value == x)  root
        else find(root.left, x) match {
            case null => find(root.right, x)
            case node => node
        }
    }
}

Update: 这里用match case总感觉不大优雅。于是,有了下面一段代码。对一个变量不能用map,就放到了list里面。还是觉得不大好。 试着用compose,andThen去组合逻辑,又显得代码太多,有点难看。

object Solution {
    def btreeGameWinningMove(root: TreeNode, n: Int, x: Int): Boolean = {
      List(find(root,x)) flatMap { x:TreeNode =>
          List(n-count(x), count(x.left), count(x.right))
      } exists (_>n/2)
    }
    def count(root:TreeNode):Int = root match {
        case null => 0
        case _ => count(root.left) + count(root.right) + 1
    }
    
    def find(root:TreeNode, x:Int):TreeNode = root match {
        case null => null
        case _ if root.value == x => root
        case _ => find(root.left, x) match {
            case null => find(root.right, x)
            case node => node
        }
    }
}

P3: 这题显然不能直接开空间, 想到用Hash做就很简单了。

class SnapshotArray(_length: Int) {
    var snap_id = 0
    val table = scala.collection.mutable.HashMap[(Int, Int), Int]() // (Snap_id, index) => value
    def set(index: Int, x: Int) {
        table.put((snap_id, index), x)
    }
    def snap(): Int = {
        snap_id += 1
        snap_id -1
    }
    def get(index: Int, id: Int): Int = {
        if(id == -1) 0
        else {
            if(table.contains((id, index))) table((id,index))
            else get(index,id-1)
        }
    }
}

P4: 贪心,一个从左, 一个从右,尽可能少的选择块数,是的两个子串相等。应该是简单题,不知道放在最后面。

object Solution {
    def longestDecomposition(A: String): Int = {
        def f(i:Int, j:Int, acc:Int = 0):Int = {
            if(i > j) acc else g(i,j) match {
                    case n => 
                    if(j-n+1 == i) f(i+n, j-n, acc+1) 
                    else f(i+n, j-n, acc+2)
                }
        }
        def g(i:Int, j:Int, d:Int = 1 ):Int = {
            if(A.substring(i,i+d) == A.substring(j-d+1,j+1)) d
            else g(i,j, d+1)
        } 
        f(0, A.length-1, 0)
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值