题意整理
- n个人站成一列,如果某个人的前面有身高比他高的,则第一个比他高的会中枪。
- 只要某个人中枪了,则荒唐度会增加对应那个人的编号,求最终的荒唐度。
方法一(暴力法)
1.解题思路
直接遍历所有的人,内层循环中找到第一个比他高的人,加上对应编号,如果找到,立即终止内层循环。
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型 n个人
* @param a int整型一维数组 ai代表第i个人的高度
* @return long长整型
*/
public long solve (int n, int[] a) {
//初始化结果变量
long res=0;
//循环遍历数组
for(int i=1;i<n;i++){
//找到第一个大于当前身高的人
for(int j=i-1;j>=0;j--){
if(a[j]>a[i]){
res+=j+1;
break;
}
}
}
return res;
}
}3.复杂度分析
- 时间复杂度:最坏情况下,总是第一个人中枪,需要遍历
次,所以时间复杂度是
。
- 空间复杂度:不需要额外的内存空间,所以空间复杂度是
。
方法二(单调栈)
1.解题思路
- 初始化一个单调栈,顺序存储所有人的编号。
- 只要栈顶对应的那个人身高小于当前身高,说明不会被打中,直接从栈中移除。这个过程结束后,如果栈中还有人,则一定是第一个大于当前身高的人,加上对应荒唐度,继续下一轮循环。
动图展示:
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型 n个人
* @param a int整型一维数组 ai代表第i个人的高度
* @return long长整型
*/
public long solve (int n, int[] a) {
//初始化结果变量
long res=0;
//初始化单调栈
LinkedList<Integer> stack=new LinkedList<>();
for(int i=0;i<n;i++){
//只要栈顶身高小于当前身高,就从栈中移除
while(!stack.isEmpty()&&a[stack.peek()-1]<=a[i]){
stack.pop();
}
//如果栈中还有元素,则栈顶一定是第一个身高大于当前元素的
if(!stack.isEmpty()){
res+=stack.peek();
}
//将每一个人的编号入栈
stack.push(i+1);
}
return res;
}
} 3.复杂度分析
- 时间复杂度:每个人最多入栈和出栈一次,所以时间复杂度是
。
- 空间复杂度:需要额外大小为n的栈,所以空间复杂度是
。

京公网安备 11010502036488号