zoukankan      html  css  js  c++  java
  • 合唱队形

    题目

    合唱队有 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);
        }
    }
    
  • 相关阅读:
    docker的网络服务
    想真正了解JAVA设计模式看着一篇就够了。 详解+代码实例
    再问你Java内存模型的时候别再给我讲堆栈方法区
    ssh爆破脚本
    ecshop3.0.0注入
    zabbix 安装配置以及漏洞检测脚本
    代理爬取
    selenium2使用记录
    初级AD域渗透系列
    用ftplib爆破FTP口令
  • 原文地址:https://www.cnblogs.com/debugxw/p/11407107.html
Copyright © 2011-2022 走看看