合唱队形
Posted debugxw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合唱队形相关的知识,希望对你有一定的参考价值。
题目
合唱队有 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);
以上是关于合唱队形的主要内容,如果未能解决你的问题,请参考以下文章