春招备战:小米算法题解

前言

在今天的麻将桌上,我收到了会长的喜讯,他在年前就已经成功斩获了字节跳动的offer,初八就要去北京报到入职了。

挺为他开心的,毕竟能去宇宙条实习,技术成长和单身问题都能漂亮解决。一边陪着会长打了会牌,一边问了些面试题,请教了些大厂面试经验。会长面的大厂还挺多的,其中有道小米的算法题,是leetcode困难级别的dp题,麻将打了一大圈还没想明白...

会长都去字节了 ,麻将赢的一百多不香了,刷题战春招,开个春招备战系列,我们一起冲。

小米面试

会长是拿下字节后,收到小米的面试邀请的,所以心态比较轻松。现在的行情,双非同学能够拿下字节的实习offer, 真个是"一日看尽长安花"。

我比较想去小米,特别喜欢小米SU7的帅气,家里用的一干物品,基本能用小米的。这不,初六写文章的我,用的是红米笔记本。

春招我已经做了心理建设了,多输(挂)几次就没关系。只要在输7次左右的时候,面上小米这样级别的公司,毕业年薪够买一辆SU7就行(20万+,哈哈)。目标有了, 开整。

算法题

会长说,他在面小米的时候,面试官出了一道leetcode 困难级别原题,动态规划的。题目是:2218. 从栈中取出 K 个硬币的最大面值和 - 力扣(LeetCode)。大家可以点开链接,先写一写,我们再讨论。

读题

一张桌子上总共有 n 个硬币 。每个栈有 正整数 个带面值的硬币。

每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里。

给你一个列表 piles ,其中 piles[i] 是一个整数数组,分别表示第 i 个栈里 从顶到底 的硬币面值。同时给你一个正整数 k ,请你返回在 恰好 进行 k 次操作的前提下,你钱包里硬币面值之和 最大为多少

在牌桌上,听会长说出这道题的时候,就有点懵。这道leetcode没刷过,回来一看,果然是道困难题。

  • 这是一道最值问题,最佳问题要不就用贪心,要不就是动态规划。动态规划比较难,大厂考dp概率大些。只要拿到状态转移方程, 很快搞定。

  • 硬币问题是道经典的动态规划题,不清楚的同学可以先去刷一下。 322. 零钱兑换 - 力扣(LeetCode)

    518. 零钱兑换 II - 力扣(LeetCode)

  • 栈,题目中的这个数据结构跟解的关系让我陷入了泥潭。

母题

开始让我迷惑,只能在栈顶操作,当我把一坨硬币摆来摆去的时候,好像跟背包问题有点像。在几坨硬币中,怎么拿,面值和最大?

  • 每一坨都是一个栈,要取的硬币是连续的栈顶元素。
  • 在某坨取的硬币个数可以看成质量
  • 在某坨取的硬币的总价值可以看成价值
  • 这个问题就变成了怎么取K次(总重量),拿到的价值最大

确信,这就是一个背包问题。总了问度娘和通义千问后,解此题的第一个关键思路是将它转变成一个分组(栈)背包问题。

大厂面试算法题一般是一组题,动态规划组题出现的最多。既然此题的母题是背包问题,我们就来先复习下01背包问题。

0-1背包模型

0-1背包问题是一个基本问题,基于这个基本问题,可以衍生出千姿百态的变种问题,这种题目就非常适合拿来构造解题模型,今儿就用上了。

0-1背包问题说的是这么回事儿:

有 n 件物品,物品体积用一个名为 w 的数组存起来,物品的价值用一个名为 value 的数组存起来;每件物品的体积用 w[i] 来表示,每件物品的价值用 value[i] 来表示。现在有一个容量为 c 的背包,问你如何选取物品放入背包,才能使得背包内的物品总价值最大?

背包问题是动态规划的标准对口问题,我们来回忆下dp的套路

  • 用递归思想,自顶向下倒推,找到最优子结构 容量c是终点,倒推,f(i, c) 表示有i件物品在容量c的背包中,且价值最大。 作为0-1背包,这个物品拿不拿就是状态转变的关键

    如果没拿,f(i, c) = f(i-1, c)

    如果拿了, f(i, c) - value[i] = f(i-1, c-w[i]) w[i]是第i件物品的重量,value[i]是第i件物品的价值

  • 从最优子结构提取的过程中,得到状态转移方程

css 复制代码
dp[i][v] = Math.max(dp[i-1][v], dp[i-1][v-w[i]] + c[i])
  • 自底向上迭代,得到最优结果。
ini 复制代码
for(let i=1;i<=n;i++) { 
    for(let v=w[i]; v<=c;v++) { 
        dp[i][v] = Math.max(dp[i-1][v], dp[i-1][v-w[i]]+value[i]) 
    } 
}
  • 优化一下,二维dp数组会浪费空间,转为一维。

0-1背包问题代码如下:

scss 复制代码
function knapsack(n, c, w, value) { 
// dp是动态规划的状态保存数组 
    const dp = new Array(c+1)).fill(0) 
    // res 用来记录所有组合方案中的最大值
    let res = -Infinity
    for(let i=1;i<=n;i++) { 
        for(let v=c;v>=w[i];v--) { 
        // 写出状态转移方程 
            dp[v] = Math.max(dp[v], dp[v-w[i]] + value[i]) 
            // 即时更新最大值 
            if(dp[v] > res) { res = dp[v] } 
        } 
    } 
    return res 
}

回到原题

ini 复制代码
function maxValueOfCoins(piles, k) {
// 状态转移方程f[i], 0 dummy  初始都为0
  let f = new Array(k + 1).fill(0);
  let sumN = 0;

  for (let pile of piles) {
      // 当前pile的长度
    let n = pile.length;
    // 计算每个堆叠的前缀和
    // pile 里的值是前面值的和
    for (let i = 1; i < n; i++) {
      pile[i] += pile[i - 1];
    }
    // 更新 sumN 为当前栈集合中前 i 个栈大小之和的最小值(不超过 k)
    // 一个栈全拿 n , k < n k, k > n 拿多少个? 
    sumN = Math.min(sumN + n, k);

    // 枚举所有可能的组合数 j,并根据物品体积计算最大价值
    // 递减式的去遍历
    for (let j = sumN; j > 0; j--) {
      // 遍历当前堆叠中前 min(n, j) 个元素
      for (let w = 0, v = pile[0]; w < Math.min(n, j); w++, v = pile[w]) {
        // 注意:此处由于数组下标从 0 开始,因此物品体积对应的下标应为 w
        f[j] = Math.max(f[j], f[j - w - 1] + v);
      }
    }
  }

  return f[k];
}

参考资料

假如您也和我一样,在准备春招。欢迎加我微信shunwuyu,这里有几十位一心去大厂的友友可以相互鼓励,分享信息,模拟面试,共读源码,齐刷算法,手撕面经。来吧,友友们!

相关推荐
B站计算机毕业设计超人23 分钟前
计算机毕业设计PySpark+Hadoop中国城市交通分析与预测 Python交通预测 Python交通可视化 客流量预测 交通大数据 机器学习 深度学习
大数据·人工智能·爬虫·python·机器学习·课程设计·数据可视化
学术头条28 分钟前
清华、智谱团队:探索 RLHF 的 scaling laws
人工智能·深度学习·算法·机器学习·语言模型·计算语言学
18号房客32 分钟前
一个简单的机器学习实战例程,使用Scikit-Learn库来完成一个常见的分类任务——**鸢尾花数据集(Iris Dataset)**的分类
人工智能·深度学习·神经网络·机器学习·语言模型·自然语言处理·sklearn
feifeikon35 分钟前
机器学习DAY3 : 线性回归与最小二乘法与sklearn实现 (线性回归完)
人工智能·机器学习·线性回归
游客52038 分钟前
opencv中的常用的100个API
图像处理·人工智能·python·opencv·计算机视觉
古希腊掌管学习的神39 分钟前
[机器学习]sklearn入门指南(2)
人工智能·机器学习·sklearn
凡人的AI工具箱1 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
咸鱼桨2 小时前
《庐山派从入门到...》PWM板载蜂鸣器
人工智能·windows·python·k230·庐山派
强哥之神2 小时前
Nexa AI发布OmniAudio-2.6B:一款快速的音频语言模型,专为边缘部署设计
人工智能·深度学习·机器学习·语言模型·自然语言处理·音视频·openai
yusaisai大鱼2 小时前
tensorflow_probability与tensorflow版本依赖关系
人工智能·python·tensorflow