笔试编程题记录:奇数乘积取数与 0246810 数列取位
- 轮次
- 笔试
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 给定一个正整数,从中选择 n 个数,要求这 n 个数的乘积为奇数,求 n 的最大值并输出。
- 按照 0,2,4,6,8,10,…… 的方式生成字符串「0246810……」,要求输出字符串中第 n 个位置的字符。
《参考解析》
第一题考的是奇偶性的本质:一串整数相乘的结果是奇数,当且仅当每一个乘数都是奇数(只要有一个偶数,乘积就是偶数)。所以最大值就是把该整数十进制表示中的所有奇数位数字全部选出来,答案是「奇数数字的个数」;如果写代码,遍历字符串统计 '1'、'3'、'5'、'7'、'9' 的出现次数即可,时间 O(位数)。实现上要注意两点:输入按字符串读而不是按整数读,避免前导零与长度问题;如果题目允许重复选同一位或要求选出的数保持相对顺序输出,要按题面再确认,别想当然。
第二题是找规律题,暴力拼接只是兜底解:拼接字符串到长度超过 n 再取第 n 位,时间复杂度 O(n) 级别,n 很大(比如 10^9)时会超时或爆内存,只能过小数据。更好的做法是分段定位:先确定第 n 位落在哪个偶数上——偶数序列 0,2,4,… 的第 k 个数是 2k,它的十进制位数是 len(2k),于是可以按位数累计长度(1 位数 5 个、2 位数 45 个、3 位数 450 个……),用减法快速跳过整段,再在目标数内部按位取出字符,整体接近 O(log n)。这类题在笔试里很常见,先写暴力保证通过、有时间再优化是合理的策略。
笔试的通用教训:编程题通过之后别急着交卷,把边界(n=0、n 超出总长度、单个数字、超大输入)跑一遍,很多失分来自 int 溢出与下标越界。这场作者也提到选择题没准备好——笔试里选择题覆盖面很广(操作系统、网络、数据库、语言细节),靠临场推理很容易丢分,建议按「错题归类 → 补知识点 → 一周后重做」的循环过两三轮,比刷更多新题有效。另外注意题目对「第 n 个位置」是从 0 还是从 1 开始计数,这类细节在笔试里直接决定成败。