[LeetCode/Scala]第143场周赛

排排坐,分糖果。

我们买了一些糖果 candies,打算把它们分给排好队的 n = num_people 个小朋友。

给第一个小朋友 1 颗糖果,第二个小朋友 2 颗,依此类推,直到给最后一个小朋友 n 颗糖果。

然后,我们再回到队伍的起点,给第一个小朋友 n + 1 颗糖果,第二个小朋友 n + 2 颗,依此类推,直到给最后一个小朋友 2 * n 颗糖果。

重复上述过程(每次都比上一次多给出一颗糖果,当到达队伍终点后再次从队伍起点开始),直到我们分完所有的糖果。注意,就算我们手中的剩下糖果数不够(不比前一次发出的糖果多),这些糖果也会全部发给当前的小朋友。

返回一个长度为 num_people、元素之和为 candies 的数组,以表示糖果的最终分发情况(即 ans[i] 表示第 i 个小朋友分到的糖果数)。

示例 1:

输入:candies = 7, num_people = 4
输出:[1,2,3,1]
解释:
第一次,ans[0] += 1,数组变为 [1,0,0,0]。
第二次,ans[1] += 2,数组变为 [1,2,0,0]。
第三次,ans[2] += 3,数组变为 [1,2,3,0]。
第四次,ans[3] += 1(因为此时只剩下 1 颗糖果),最终数组变为 [1,2,3,1]。
示例 2:

输入:candies = 10, num_people = 3
输出:[5,2,3]
解释:
第一次,ans[0] += 1,数组变为 [1,0,0]。
第二次,ans[1] += 2,数组变为 [1,2,0]。
第三次,ans[2] += 3,数组变为 [1,2,3]。
第四次,ans[0] += 4,最终数组变为 [5,2,3]。

提示:

1 <= candies <= 10^9
1 <= num_people <= 1000

object Solution {
    def distributeCandies(k: Int, N: Int): Array[Int] = {
        val ans = Array.fill(N)(0)
        def f(i:Int, amount:Int, acc:Int):Unit = amount match {
            case x if x <= acc => ans(i) += x
            case _ => ans(i) += acc; f((i+1) % N, amount - acc, acc + 1)
        }
        f(0,k,1)
        ans
    }
}

在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。

如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;

而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。
在这里插入图片描述

给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。

示例 1:

输入:label = 14
输出:[1,3,4,14]
示例 2:

输入:label = 26
输出:[1,2,6,10,26]

提示:

1 <= label <= 10^6

object Solution {
 def pathInZigZagTree(label: Int): List[Int] = {
    def pow2(x:Int):Int = Math.pow(2,x).toInt
    def g(x:Int, i:Int):Int =  i % 2 match {
        // use Math to solve
        // i-th layer: 2^(i-1), 2^i -1
        // first a0 = 2^i -1 , d = -1, a0+n*d = x => n = a0 - x 
        case 0 => (pow2(i)-1 - x) / 2 + pow2(i-2)
        // first a0 = 2^(i-1), d = 1, a0 + n = x => n = x - a0
        case 1 => pow2(i-1) - 1 - (x - pow2(i-1))/2
    }

    def log2(x:Int, acc:Int = 0):Int = x match {
      case 0 => acc
      case _ => log2(x / 2, acc + 1)
    }

    def f(x:Int, acc:List[Int]):List[Int] = x match {
      case 1 => 1::acc
      case _ => f(g(x, log2(x)),x::acc)
    }
    f(label,Nil)
  }
}

附近的家居城促销,你买回了一直心仪的可调节书架,打算把自己的书都整理到新的书架上。

你把要摆放的书 books 都整理好,叠成一摞:从上往下,第 i 本书的厚度为 books[i][0],高度为 books[i][1]。

按顺序 将这些书摆放到总宽度为 shelf_width 的书架上。

先选几本书放在书架上(它们的厚度之和小于等于书架的宽度 shelf_width),然后再建一层书架。重复这个过程,直到把所有的书都放在书架上。
在这里插入图片描述
需要注意的是,在上述过程的每个步骤中,摆放书的顺序与你整理好的顺序相同。 例如,如果这里有 5 本书,那么可能的一种摆放情况是:第一和第二本书放在第一层书架上,第三本书放在第二层书架上,第四和第五本书放在最后一层书架上。

每一层所摆放的书的最大高度就是这一层书架的层高,书架整体的高度为各层高之和。

以这种方式布置书架,返回书架整体可能的最小高度。

示例:

输入:books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelf_width = 4
输出:6
解释:
3 层书架的高度和为 1 + 3 + 2 = 6 。
第 2 本书不必放在第一层书架上。

提示:

1 <= books.length <= 1000
1 <= books[i][0] <= shelf_width <= 1000
1 <= books[i][1] <= 1000

object Solution {
   def minHeightShelves(A: Array[Array[Int]], w: Int): Int = {
    val dp = Array.fill(A.length+1)(Int.MaxValue)
    dp(0) = 0
    for{i <- 0 until A.length}{
      var width = 0
      var height = 0
      for{j <- i until A.length}{
        width+= A(j)(0)
        height = height max A(j)(1)
        if(width <= w)
          dp(j+1) = dp(j+1) min (dp(i)+ height)
      }
    }
    dp.last
  }
}

给你一个以字符串形式表述的 布尔表达式(boolean) expression,返回该式的运算结果。

有效的表达式需遵循以下约定:

“t”,运算结果为 True
“f”,运算结果为 False
“!(expr)”,运算过程为对内部表达式 expr 进行逻辑 非的运算(NOT)
“&(expr1,expr2,…)”,运算过程为对 2 个或以上内部表达式 expr1, expr2, … 进行逻辑 与的运算(AND)
“|(expr1,expr2,…)”,运算过程为对 2 个或以上内部表达式 expr1, expr2, … 进行逻辑 或的运算(OR)

示例 1:

输入:expression = “!(f)”
输出:true
示例 2:

输入:expression = “|(f,t)”
输出:true
示例 3:

输入:expression = “&(t,f)”
输出:false
示例 4:

输入:expression = “|(&(t,f,t),!(t))”
输出:false

提示:

1 <= expression.length <= 20000
expression[i] 由 {’(’, ‘)’, ‘&’, ‘|’, ‘!’, ‘t’, ‘f’, ‘,’} 中的字符组成。
expression 是以上述形式给出的有效表达式,表示一个布尔值。

object Solution {
  case class Expr(x:Boolean, op:String, flag:Boolean)
  def parseBoolExpr(expression: String): Boolean = {
    def solve(l:List[Expr]):List[Expr] = {
      var nl = l
      var acc = List.empty[Expr]
      while(!nl.head.flag){
        acc ::= nl.head
        nl = nl.tail
      }
      nl.head.op match {
        case "Or" => Expr(acc.map(_.x).reduce(_|_),"",false)::nl.tail
        case "And" => Expr(acc.map(_.x).reduce(_&&_),"",false)::nl.tail
        case "Not" => Expr(!acc.head.x, "",false)::nl.tail
      }
    }
    def f(l:List[Char], stack:List[Expr]):Boolean = l match {
      case ','::t => f(t, stack)
      case '|'::t => f(t, Expr(true, "Or", true)::stack)
      case '!'::t => f(t, Expr(true, "Not", true)::stack)
      case '&'::t => f(t, Expr(true, "And", true)::stack)
      case '('::t => f(t, stack)
      case ')'::t => f(t, solve(stack))
      case 'f'::t => f(t, Expr(false, "", false)::stack)
      case 't'::t => f(t, Expr(true, "", false)::stack)
      case h::t => f(t,stack)
      case Nil => stack.head.x
    }

    f(expression.toList,Nil)
  }
}```

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值