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);
        }
    }
    
  • 相关阅读:
    sql删除重复数据,保留一条
    sql列转行
    异步线程:一次性发送大量邮件
    限制接口的访问次数
    Kibana(安装及其简单crud)
    Elasticsearch(简介及其单节点搭建)
    大数据(日志分析)项目
    大数据(sqoop)
    大数据(Hive数据库、表的详解及其Hive数据导入导出)
    大数据(Hive的MetaStore切换及其Hive的语法细节)
  • 原文地址:https://www.cnblogs.com/debugxw/p/11407107.html
Copyright © 2011-2022 走看看