字节跳动面到这道题,有的读者一脸懵逼,有的读者笑嘻嘻

2024-02-13 03:30

本文主要是介绍字节跳动面到这道题,有的读者一脸懵逼,有的读者笑嘻嘻,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是程序员吴师兄。

今天在逛 LeetCode 评论区的时候,发现了一道题目近期频繁出现在字节跳动的面试中,不得不感慨一句:面试官真喜欢考察 动态规划 呀!

今天就来详解这道题目,希望能帮助你在面试的时候笑嘻嘻:)

题目描述是这样子的。

题目描述

编写一个程序,找出第 n 个丑数。

丑数就是质因数只包含 2, 3, 5 的正整数

示例:

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。

说明: 

  • 1 是丑数。

  • n 不超过1690。

题目来源:https://leetcode-cn.com/problems/ugly-number-ii/

题目解析

题目让你找出第 n 个丑数。对于丑数,题目也给出了定义,丑数是正整数,并且它的质数因子仅包含 2, 3, 5。另外,整数 1 算是一个最小的丑数。

一开始看到这道题,感觉就是一道简单的数学乘法题,一个循环不就搞定了?

但其实并不是,如果仅仅使用简单的乘法循环,你并不知道下一个数所在的序列位置

另外,暴力的深度优先搜索遍历在这道题上也不适用,因为你并不确定搜索的结束条件,到底找到哪个数才停止递归呢?

但如果进一步思考,你会发现 后面的数可以由前面的数推出来

用通俗一点的话讲就是,问题的解可以由子问题的解推出来。这句话是不是很熟悉?是的,动态规划的特点

但这里比较难想到的地方是,子问题之间的联系是什么?

比如我们定义动态规划状态,dp[i] 表示第 i 个丑数,那么这个状态怎么由前面的状态推导得出?

这里的重点是,前面的每一个数(状态)都可以乘上 2, 3, 5 来形成一个新的状态,新的状态是肯定符合丑数的定义。

但是我们的关注点是下一个状态是什么,比如第一个状态是 1,它可以乘以上面 3 个数的其中一个,结果为 2、3、5,取最小的 1 × 2 = 2 为第二个状态。

到这时,我们需要考虑第三个状态是什么。

从第一个状态 1 出发,我们得到了 2,但是从第一个状态 1 出发,我们还可以得到 3,5。另外,从第二个状态 2 出发我们可以得到  4 。

你可能会说,从第二个状态 2 出发我们还可以得到 6、10。没错,但是乘上 3、5 在 1 的时候考虑比在 2 处考虑得出的状态更小。

也就是说,第三个状态的值在 1 × 3、1 × 5、 2 × 2 三者里面进行选择。

通过上面的描述,你可能 找到规律 了:每个状态都可以乘上 2, 3, 5

但是状态乘上这些质数因子的时候,必须保证前面的状态已经乘过了对应的质数因子,因为前面会得到更小的值,我们需要的是 按序查找

由此,我们可以创建 3 个指针 p2、p3、p5,分别表示这 3 个质数因子此时应该乘上第几个状态。

补充:这里来具体解释一下 p2、p3、p5 的含义(来源于 LeetCode 题解区 zzxn)。

实际上 pi 的含义是有资格同 i 相乘的最小丑数的位置

这里资格指的是:如果一个丑数 dp[pi] 通过乘以 i 可以得到下一个丑数,那么这个丑数 dp[pi] 就永远失去了同 i 相乘的资格(没有必要再乘了),我们把 pi++ 让 dp[pi] 指向下一个丑数即可。

不懂的话举例说明:

一开始,丑数只有{1},1可以同 2 、3 、5 相乘,取最小的 1 ×  2 = 2 添加到丑数序列中。

现在丑数中有 {1,2} ,在上一步中,1 已经同 2 相乘过了,所以今后没必要再比较 1 × 2 了,我们说 1 失去了同 2 相乘的资格。

现在 1 有与 3、5 相乘的资格,2 有与 2、3、5 相乘的资格,但是 2 × 3 和 2 × 5 是没必要比较的,因为有比它更小的 1 可以同 3、5 相乘,所以我们只需要比较 1 × 3 、1 × 5 、 2 × 2 。

依此类推,每次我们都分别比较有资格同 2、3、5 相乘的最小丑数,选择最小的那个作为下一个丑数,假设选择到的这个丑数是同 i( i = 2、3、5)相乘得到的,所以它失去了同 i 相乘的资格,把对应的 pi++ ,让 pi 指向下一个丑数即可。

这样的思路可以在 O(n) 的时间完成这道题目。

参考代码

class Solution {public int nthUglyNumber(int n) {if( n < 1) return 0;int p2 = 0;int p3 = 0;int p5 = 0;int[] dp = new int[n];dp[0] = 1;for (int i = 1; i < n; i ++) {// 比较此时可能的状态,取最小的那个dp[i] = Math.min(dp[p2] * 2, Math.min(dp[p3] * 3, dp[p5] * 5));// 更新指向// 注意这里不能只更新一个指针// 比如 6,可以由 2 * 2 * 2 形成,也可以由 2 * 3 组成if( dp[i] == dp[p2] * 2) p2++;if( dp[i] == dp[p3] * 3) p3++;if( dp[i] == dp[p5] * 5) p5++;}return dp[n - 1];}
}

---

由 五分钟学算法 原班人马打造的公众号:图解面试算法,现已正式上线!
接下来我们将会在该公众号上,为大家分享优质的算法解题思路,坚持每天一篇原创文章的输出,视频动画制作不易,感兴趣的小伙伴可以关注点赞一下哈!

这篇关于字节跳动面到这道题,有的读者一脸懵逼,有的读者笑嘻嘻的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/704363

相关文章

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

JVM - 字节码文件详解

文章目录 目录 文章目录 1. 无关性基石 2. Class类文件结构 magic- 魔数 主副版本号 常量池 访问标志 类索引,父类索引与接口索引集合 字段 方法 属性 3. 类加载机制 类的生命周期 类加载过程 加载 连接 验证 准备 解析 初始化 4. 类加载器 类与类加载器 类加载器的分类 启动类加载器  扩展类加载器 应用程序类加

SylixOS write 0 字节问题

1 问题描述 在移植中间件过程中,在SylixOS调用write函数写入0字节的数据到文件中时,会导致对应的中间件测试用例失败,失败的原因是文件系统中的write函数在Linux系统和SylixOS有区别,两种实现的差别如下。 2 write函数的实现机制 2.1 SylixOS实现机制 在SylixOS下通过write 函数写数据到普通文件中时,第一步会判断写入的数据是否为0,如果是0直

CPU大小端字节序的检测

机器的字节序有两种,即大端字节序和小端字节序。 大端字节序:在内存中,低地址存放数据的 高位,高地址存放数据的 低位 小端字节序:在内存中,低地址存放数据的 低位,高地址存放数据的 高位 如例:定义数据  a = 0x01020304 小端方式:01 02 03 04 大端方式:04 03 02 01 那么如何判断呢,方式如下--> 一、 指

68-java字符流和字节流

Java中的字符流和字节流是用于处理输入/输出的两大类。字符流主要用于处理字符数据,而字节流可以处理任何类型的数据。 字符流: Reader:用于读取字符流的抽象类。 Writer:用于写入字符流的抽象类。 字节流: InputStream:用于读取字节流的抽象类。 OutputStream:用于写入字节流的抽象类。 下面是使用字符流和字节流的简单示例: 字符流示例(文件复

1字节的UTF-8序列的字节1无效

使用DOMReader解析XML文档时候报错”1字节的UTF-8序列的字节1无效”,我这里的解决方法。 1.手动将< ? xml version=”1.0” encoding=”UTF-8”?>中的UTF-8更改成UTF8,这样就可以了。 2.使用文本编译器把xml文档改成以UTF8无BOM编码格式就可以了。

SparkSQL在字节跳动的应用实践和优化实战

来源:字节跳动白泉的分享 作者:大数据技术与架构整理 点击右侧关注,大数据开发领域最强公众号! 点击右侧关注,暴走大数据! By  大数据技术与架构 场景描述: 面对大量复杂的数据分析需求,提供一套稳定、高效、便捷的企业级查询分析服务具有重大意义。本次演讲介绍了字节跳动

使用Python通过字节串或字节数组加载和保存PDF文档

处理PDF文件的可以直接读取和写入文件系统中的PDF文件,然而,通过字节串(byte string)或字节数组(byte array)来加载和保存PDF文档在某些情况下更高效。这种方法不仅可以提高数据处理的灵活性,允许开发者在内存中直接操作PDF,而且还能增强安全性,同时方便跨应用传输和网络传输。 本文将介绍如何使用Python通过字节串或字节数组来加载和保存PDF文档。 文章目录 创建P

所以说读者们才是最优秀的 | 某读者喜提offer(+85%)后的分享

点击上方蓝色字体,选择“设为星标” 回复”资源“获取更多资源 这是小编的一个读者喜提offer后在群里做的分享,文中隐藏了读者的个人隐私信息,小编这里把他的面经分享出来供大家学习。  群友们看到后都纷纷表示【我酸了,现在我就是个柠檬精系列】。 小编现在也是个柠檬精????????????????????????????????。 小编现在是群里最菜的了。     关于如何学习/准备面试的总结

Oracl查询报错:ORA-29275: 部分多字节字符

报错描述 --使用oracl的sql查询时候,此sql无误:SELECT DISTINCT MS_BRDA.MZHM as patientId,MS_BRDA.BRXM as name,CASEWHEN MS_BRDA.BRXB = 1 THEN '男'WHEN MS_BRDA.BRXB = 2 THEN '女'ELSE '未知'END