• 合唱队形


    题目

    合唱队有 N 个人,编号为 0 到 N - 1,Height[i] 代表第 i 个人的身高,所有人站成一排。

    现要将这 N 个人分为若干组,每一组的人员编号连续,且组内人员可以任意交换位置。

    使得这 N 个人的身高从左往右为一个非递减数列。问最多可将其分为多少组?

    输入描述

    输入一个正整数 N 代表合唱队人数,接下来一行输入 N 个数代表每个人的身高

    输出描述

    输出一个数代表最多可将其分为多少组

    样例输入

    4
    2 1 3 2

    样例输出

    2

    说明

    分为两组 [2, 1] [3, 2],组内交换顺序即可得到 [1, 2], [2, 3]

    AC 代码

    import java.util.Scanner;
    
    /**
     * 关键思路:
     * 找到某个元素左边的最大值和右边的最小值
     * 如果leftMax[i] <= rightMin[i+1],则可以从i的右边界直接分开
     * <p>
     * 使用两个辅助数组:
     * leftMax[]:记录当前元素左边的最大值(包括当前值)
     * rightMin[]:记录当前元素右边的最小值(包括当前值)
     */
    public class Main {
    
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            int N = scanner.nextInt();
            // 特殊情况
            if (N == 0 || N == 1)
                System.out.println(N);
            // 获取身高
            int[] height = new int[N];
            for (int i = 0; i < N; i++)
                height[i] = scanner.nextInt();
    
            int[] leftMax = new int[N];
            int[] rightMin = new int[N];
            leftMax[0] = height[0];
            rightMin[N - 1] = height[N - 1];
            for (int i = 1; i < N; i++) {
                leftMax[i] = Math.max(leftMax[i - 1], height[i]);
            }
            for (int i = N - 2; i >= 0; i--) {
                rightMin[i] = Math.min(rightMin[i + 1], height[i]);
            }
            int res = 1;
            for (int i = 0; i < N - 1; i++) {
                if (leftMax[i] <= rightMin[i + 1]) {
                    res++;
                }
            }
            System.out.println(res);
        }
    }
    
  • 相关阅读:
    栈的经典运用-求值数学表达式
    java中Stack的源码解析
    java-背包的实现
    数据库的事务的特性及隔离级别
    EnumMap的用法和源码解析
    java final关键字的解析
    java中的static关键字解析
    XPath如何定位dom节点
    java 枚举(enum) 详细用法
    jdk动态代理
  • 原文地址:https://www.cnblogs.com/debugxw/p/11407107.html
Copyright © 2020-2023  润新知