小C的数组排序挑战 | 豆包MarsCode AI刷题

64 阅读3分钟

问题描述

小C手里有一个长度为 n 的数组 a。她可以对数组进行一些操作,每次操作的效果是:将数组中每个元素 ai 加上其对应的下标 i 。也就是说,经过一次操作后,数组中的元素 a_i 将变为 a_i+i。小C的目标是通过尽可能少的操作次数,使数组 a 变成严格升序排列,即满足 a_1<a_2<a_3<…<a_n。请你帮助小C计算出使数组 a 达到严格升序所需的最少操作次数。

例如,对于数组 [1, 1, 4, 5, 1, 4],经过5次操作后,它变成了 [6, 11, 19, 25, 26, 34],满足严格升序。

问题理解

由题目可知,需要通过最少的操作次数,使得数组 a 变成严格升序排列。每次操作会将数组中的每个元素 a_i 加上其对应的下标i

解题思路

  1. 初始检查:首先检查数组是否已经是严格升序的。如果是,则不需要任何操作。
  2. 模拟操作:每次操作后,数组中的每个元素 a_i 都会增加i。需要模拟这个过程,直到数组变成严格升序。
  3. 计数操作次数:在每次操作后,检查数组是否已经变成严格升序。如果是,则记录操作次数并返回。

代码实现

public class Main {
    public static int solution(int n, int[] a) {
        // write code here
        int operations = 0;
        
        // 检查数组是否已经是严格升序
        while (!isStrictlyIncreasing(a)) {
            // 模拟操作:将每个元素加上其下标
            for (int i = 0; i < n; i++) {
                a[i] += i;
            }
            operations++;
        }
        
        return operations;
    }

    // 检查数组是否严格升序
    private static boolean isStrictlyIncreasing(int[] a) {
        for (int i = 0; i < a.length - 1; i++) {
            if (a[i] >= a[i + 1]) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(solution(6, new int[]{1, 1, 4, 5, 1, 4}) == 5);
        System.out.println(solution(3, new int[]{1, 1, 1}) == 1);
        System.out.println(solution(5, new int[]{3, 2, 2, 3, 2}) == 2);
    }
}

所涉及知识点

1. 数组操作

  • 数组遍历:需要遍历数组中的每个元素,检查其是否满足严格升序的条件。
  • 数组元素更新:每次操作后,都需要更新数组中的每个元素,使其加上对应的下标。

2. 循环与条件判断

  • while 循环:用于不断进行操作,直到数组变成严格升序。
  • for 循环:用于遍历数组中的每个元素,进行更新操作。
  • 条件判断:在每次操作后,检查数组是否已经变成严格升序。

3. 函数与方法

  • 自定义方法:定义了一个 isStrictlyIncreasing 方法来检查数组是否严格升序。
  • 主方法solution 方法用于模拟操作并计数操作次数。

4. 算法设计

  • 模拟算法:通过模拟每次操作,逐步更新数组,直到满足严格升序的条件。
  • 贪心算法:每次操作都尽可能地使数组接近严格升序,直到达到目标状态。

5.  边界条件处理

  • 初始检查:在开始操作之前,先检查数组是否已经是严格升序的,避免不必要的操作。

总结

通过对此题的练习,我不仅掌握了如何进行数组遍历以及数组元素更新,还学习到了如何在实践中将循环与条件判断、函数与方法、算法设计、以及边界条件处理等多个编程知识点组合在一起使用,提高了对已学知识点进行组合运用的熟练度。