数字增殖问题-青训营X豆包MarsCode 技术训练营刷题分享 | 豆包MarsCode AI 刷题

119 阅读4分钟

一、题目解析:数字增殖问题

问题描述

给定一个正整数 n,定义一次"增殖"操作如下:

  • 将数字 n 转化为一个包含 1 到 n 的递增序列。例如:当 n = 4 时,一次增殖后变为序列 [1, 2, 3, 4]

现给定三个正整数:

  • 初始数字 n
  • 增殖次数 k
  • 位置索引 p(从1开始计数)

请计算经过 k 次增殖操作后,序列中第 p 个位置的数字。如果 p 超出序列长度,则返回 -1

输入

  • n: 初始数字
  • k: 增殖次数
  • p: 位置索引

返回

  • 序列中第 p 个位置的数字,如果 p 超出序列长度,则返回 -1

参数限制

  • 1 <= n <= 10^4
  • 1 <= k <= 10^4
  • 1 <= p <= 10^9

题目思路

  1. 初始化序列:首先,将数字 n 转化为一个包含 1 到 n 的递增序列。例如,当 n = 4 时,初始序列为 [1, 2, 3, 4]
  2. 进行增殖操作:进行 k 次增殖操作,每次将当前序列中的每个数字 m 转化为 [1, 2, ..., m]。例如,初始序列 [1, 2, 3] 经过一次增殖后变为 [1, 1, 2, 1, 2, 3]
  3. 检查序列长度:在每次增殖操作后,检查新序列的长度。如果新序列的长度超过 p,则直接返回第 p 个位置的数字。
  4. 返回结果:如果所有增殖操作完成后,序列长度仍未超过 p,则返回 -1

具体操作步骤

  1. 初始化序列

    • 创建一个列表 currentList,包含从 1 到 n 的数字。
    • 例如,当 n = 4 时,currentList 初始化为 [1, 2, 3, 4]
  2. 进行增殖操作

    • 进行 k 次增殖操作,每次操作如下:

      • 创建一个新的列表 newList
      • 遍历 currentList 中的每个数字 num
      • 对于每个数字 num,将 [1, 2, ..., num] 添加到 newList 中。
      • 如果 newList 的长度超过 p,则直接返回 newList 中第 p 个位置的数字。
      • 将 newList 赋值给 currentList,准备进行下一次增殖操作。
  3. 检查序列长度

    • 在每次增殖操作后,检查 newList 的长度。如果 newList 的长度超过 p,则直接返回第 p 个位置的数字。
    • 如果所有增殖操作完成后,currentList 的长度仍未超过 p,则返回 -1

代码实现

public static int solution(int n, int k, int p) {
        List<Integer> oldlist = new ArrayList<Integer>();
        List<Integer> newlist = new ArrayList<Integer>();
        List<Integer> result = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            oldlist.add(i);
        }
        result.addAll(oldlist);
        k--;
        while (k-- > 0) {
            for (int i = 0; i < oldlist.size(); i++) {
                for(int j = 1; j <= oldlist.get(i) ;j++) {
                    if(newlist.size()>p){
                        break;
                    }
                    newlist.add(j);
                }
                if(newlist.size()>p){
                    break;
                }
            }
            oldlist.clear();
            result.clear();
            oldlist.addAll(newlist);
            result.addAll(newlist);
            newlist.clear();
        }
        if(result.size()<p){
            return -1;
        }
        return result.get(p-1);
    }

二、知识总结:列表操作和嵌套循环的应用

Java 中的 List 用法

  • 特性List 是一个有序的集合,允许重复的元素。ArrayList 是 List 接口的一个常用实现类,基于动态数组实现。

  • 常用方法

    • add(E e): 在列表末尾添加元素。
    • get(int index): 获取指定索引位置的元素。
    • size(): 返回列表中的元素数量。
    • clear(): 清空列表中的所有元素。
    • addAll(Collection<? extends E> c): 将指定集合中的所有元素添加到列表中。

列表操作

  • 特性:列表是一种动态数组,可以存储任意类型的元素,并且支持动态扩展。
  • 实际应用:列表常用于需要频繁插入、删除和访问元素的场景,如实现队列、栈等数据结构。

嵌套循环

  • 特性:嵌套循环是指一个循环体内包含另一个循环。它常用于处理多维数组或需要多层次遍历的场景。
  • 实际应用:嵌套循环广泛应用于矩阵操作、图的遍历、组合生成等场景。

学习建议

  • 多练习类似的题目:尝试解决更多涉及列表操作和嵌套循环的问题,如“矩阵旋转”、“全排列生成”等。
  • 理解并手动推导:手动推导嵌套循环的操作过程,直观感受其工作原理和性能特点。
  • 阅读相关文档和教程:深入学习列表和嵌套循环的实现细节和使用方法。

通过这些方法,可以更好地掌握列表操作和嵌套循环的应用,提升算法设计和实现的能力。