1.下一个较大元素(1)
题目描述
现在我们有一个int数组,请你找出数组中每个元素的下一个比它大的元素。给定一个int数组A及数组的大小n,请返回一个int数组,代表每个元素比他大的下一个元素,若不存在则为-1。保证数组中元素均为正整数。
测试样例:
[11,13,10,5,12,21,3],7
返回:[13,21,12,12,21,-1,-1]
import java.util.Stack;
public class Test{
public static void main(String[] args){
int arr[]={11,13,10,5,12,21,3};
int n=7;
// int res[]=findNext_1(arr, n);
int res[]=findNext_2(arr, n);
for(int i:res){
System.out.print(i+" "); //输出 13 21 12 12 21 -1 -1
}
}
//方法1:用栈来实现(运行时间:587ms 占用内存:18284k)
public static int[] findNext_1(int[] A, int n) {
Stack<Integer> stack=new Stack<Integer>(); //栈用来存放数组的下标
for(int i=0;i<n;i++){
while(!stack.isEmpty()&&A[stack.peek()]<A[i]){ //后面的值如果比栈顶元素大,则换位
A[stack.pop()]=A[i];
}
stack.push(i);
}
while(!stack.isEmpty()){ //最后找不到匹配的对应位置赋值为-1
A[stack.pop()]=-1;
}
return A;
}
//方法2:用一个flag做是否找到的标志,然后用单纯的数组 (运行时间:537ms 占用内存:18344k)
public static int[] findNext_2(int[] A, int n) {
int arr[]=new int[n];
arr[n-1]=-1;
for(int i=0;i<n;i++){
Boolean flag=false; //每次进经过j循环后更新flag的值
for(int j=i+1;j<n;j++){
if(A[j]>A[i]){
arr[i]=A[j];
flag=true;
break;
}
}
if(flag==false){ //未进循环说明没进入if判断中,即没找到赋值为-1
arr[i]=-1;
}
}
return arr;
}
}
2.下一个较大元素(2)
题目描述
现在有一个数组,请找出数组中每个元素的后面比它大的最小的元素,若不存在则为-1。
给定一个int数组A及数组的大小n,请返回每个元素所求的值组成的数组。保证A中元素为正整数,且n小于等于1000。
测试样例:
[11,13,10,5,12,21,3],7
[12,21,12,12,21,-1,-1]
import java.util.ArrayList;
import java.util.Collections;
import java.util.Stack;
public class Test{
public static void main(String[] args){
int arr[]={11,13,10,5,12,21,3};
int n=7;
int res[]=findNext_1(arr, n);
for(int i:res){
System.out.print(i+" "); //输出 12,21,12,12,21,-1,-1
}
}
//方法1:比较偷懒的方法,借助ArrayList,利用Collections的sort方法对集合进行排序
public static int[] findNext_1(int[] A, int n) {
int arr[]=new int[n];
ArrayList<Integer> list=null;
for(int i=0;i<n;i++){
list=new ArrayList<Integer>(); //每经过一次循环,list指针指向一个新的对象
for(int j=i+1;j<n;j++){
if(A[j]>A[i])
list.add(A[j]);
}
if(list.size()==0)
arr[i]=-1;
else{
Collections.sort(list); //直接利用Collections的sort方法对集合list进行排序
arr[i]=list.get(0);
}
}
return arr;
}
//方法2:单纯的通过数组来实现
public static int[] findNext_2(int[] A, int n) {
int []arr=new int[n];
for(int i=0;i<n;i++){ //首先将arr各位都赋值为-1
arr[i]=-1;
}
for(int i=0;i<n;i++){
for (int j = i+1; j < n; j++) {
if(A[j]>A[i]){
if(arr[i]==-1){
arr[i]=A[j];//将第一个大于A[i]的放在arr[i]
}else{
arr[i]=A[j]>arr[i]?arr[i]:A[j]; //如果最小值的话,更新arr[i]的值
}
}
}
}
return arr;
}
/*方法3:通过栈来实现,stack顶端->低端呈现出一种从小到大的排序过程,
将stack顶端比当前A[i]小的存在stakc2中,大的放在stack中*/
public static int[] findNext_3(int[] A, int n) {
int[] res = new int[n];
Stack<Integer> stack = new Stack<>();
Stack<Integer> stack2 = new Stack<>(); //stack2为引入的中间变量,存放比当前值小的元素
for (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && stack.peek() <= A[i]) {
stack2.push(stack.pop());
}
res[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(A[i]);
while (!stack2.isEmpty()) {
stack.push(stack2.pop());
}
}
return res;
}
}