当前位置:首页 > 牛客 > 【牛客234288题解析】前缀计算与迭代查找第K个数:高效求解不含前导零的序列元素

【牛客234288题解析】前缀计算与迭代查找第K个数:高效求解不含前导零的序列元素

4个月前 (07-28)

【牛客234288题解析】前缀计算与迭代查找第K个数:高效求解不含前导零的序列元素 牛客题解 前缀和 迭代 二进制 C++ 第1张

一、题目解读

牛客234288题要求在一个由1到n的数字组成的序列中,找到第K个不含前导零的数。例如,当n=12时,序列为[1,2,3...12],若K=5,则答案为5。题目关键在于避免暴力生成所有数字并排序,需设计高效算法直接定位目标元素。

二、解题思路

用户代码采用前缀计算与迭代的方法,核心思想是:

1. 通过计算以当前数字为前缀的子中数字个数(如“1”前缀包含[1,10]共10个数),判断第K个数是否在该子树内。

2. 若子树包含K,则进入该前缀分支(如curr=1→curr=10);否则跳过该子树,继续迭代下一个前缀。

3. 利用二进制拆分思想,减少不必要的数字生成,实现O(log n)时间复杂度。

三、解题步骤

1. 初始化:

    curr=1(从第一个数字开始),k--(因后续循环从0开始计数)。

2. 计算前缀子树中的数字个数:

    使用first和last变量模拟前缀扩展(如1→10、12→120等)。

    通过steps += min(n+1, last) - first计算子树大小,避免超出n范围。

3. 判断子树是否包含目标K:

    若steps <= k,说明第K个数不在当前子树,更新curr++(移至下一个前缀)和k -= steps(扣除已跳过数字)。

    若steps > k,说明K在当前子树中,更新curr *= 10(进入子树分支),k--(继续查找子树中的第K个)。

4. 循环终止与结果返回:

当k=0时,当前curr即为第K个数。

四、代码与注释

class Solution {
public:
    int findKth(int n, int k) {
        int curr = 1; // 当前前缀数字
        k--; // 初始化为第一个数1(因循环从0开始计数)
        while (k > 0) {
            long steps = 0; // 当前前缀子树的数字个数
            long first = curr; // 子树起始数字(如1→10的1)
            long last = curr + 1; // 子树结束数字(如1→10的10)
            
            // 计算以curr为前缀的数字个数
            while (first <= n) {
                steps += min((long)n + 1, last) - first; // 避免超出n范围
                first *= 10; // 扩展前缀(如1→10→100)
                last *= 10; // 对应结束位置(如10→100→1000)
            }
            
            if (steps <= k) { // 不在当前子树中
                curr++; // 移至下一个前缀(如1→2)
                k -= steps; // 扣除已跳过的数字
            } else { // 在当前子树中
                curr *= 10; // 进入子树分支(如1→10)
                k--; // 继续查找子树中的第K个
            }
        }
        return curr; // 循环结束时,curr即为第K个数
    }
};

注释说明:代码通过迭代与数学推导,高效定位目标元素,避免生成完整序列。

五、总结

该解法通过前缀计算与迭代,将问题转化为子树查找,巧妙利用二进制拆分思想,大幅降低时间复杂度至O(log n)。关键点在于:

1. 子树数字个数的精确计算(避免溢出与边界问题)。

2. 循环不变量维护:k始终表示剩余需要查找的位数。

3. 前缀扩展的数学推导(如1→10→100)。

在实际应用中,此类算法适用于需要快速定位有序序列中特定元素的场景,尤其当数据量庞大时效果显著。需注意对边界条件(如n+1与min函数)的处理,确保正确性。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣5:中心扩散法 轻松破解最长回文子串

力扣5:中心扩散法 轻松破解最长回文子串

题目解读:在一个给定的字符串中,我们需要找到最长的回文子串。回文是指正读反读都相同的字符串,如"aba"、"abba"都是回文。这个问题看似简单,但要在字符串中...

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

题目重解给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们的目标是找到一条路径,使得路径上经过的数字总和最大。这个问题在实际中有许多应用场景,如最优路径规划、...

手搓顺序表类代码注释与详解:从零实现动态数组(新手教程)

一、简介和特点顺序表(Sequential List)是数据结构中基础的一种线性表,其特点是将数据元素存储在连续的内存空间中。通过数组实现,支持随机访问(即通过索引直接访问元素),适用于频繁随机读取的...

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

一、题目解读洛谷1220题要求计算在n个位置放置灯的情况下,通过关闭连续区间灯并移动至区间端点,使得总耗电量最小。需考虑灯的功率与位置差异,设计高效的算法求解最优策略。二、解题思路1. 动态规划 +...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

一、题目解读洛谷2652题要求对一组扑克牌进行排序,目标是找到最少需要调整的次数,使得所有牌形成同花顺。题目中,扑克牌由花色和数字组成,需先按花色排序,再在同花色内按数字排序。核心难点在于如何处理花色...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。