标签:类型 add 变化 分析 入栈 数组 print java ret
/**
* 题目: 第七题的进阶问题
* 给定一个可能含重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置。
* 返回所有的位置信息。
* 分析:
* 初始arr=[3,1,3,4,3,5,3,2,2],stack从栈顶到栈底为:{}
* 位置角标 0,1,2,3,4,5,6,7,8
* 1.遍历到arr[0]==3时,发现stack为空,直接将0位置的角标存入到stack栈内,此时stack从栈顶到栈底的元素依次是{0位置(3)};
*
* 2.遍历到arr[1]==1时,此时stack栈顶的元素是位置0,由于arr[0]>arr[1],若将1位置放入栈内,不满足stack元素从栈顶到栈底
* 元素是依次减小的变化规律,故将0位置弹出stack栈,此时stack为空,即为{},由于弹出的是位置0,栈内为空所以res={-1,1};由于
* stack为空,此时将位置1压入栈内,stack从栈顶到栈底的元素依次是{1位置(1)};
*
* 3.遍历到arr[2]==3时,发现将2位置直接压入栈内不会破坏stack栈从栈顶到栈底元素依次减小的规律,故将2位置压入栈内,此时stack
* 栈从栈顶到栈底的元素依次是{2位置(3),1位置(1)};
*
* 4.遍历到arr[3]==4时,发现将3位置直接压入栈内不会破坏stack栈从栈顶到栈底元素依次减小的规律,故将3位置压入栈内,此时stack
* 栈从栈顶到栈底的元素依次是{3位置(4),2位置(3),1位置(1)};
*
* 5.遍历到arr[4]==3时发现,将4位置直接压入栈内会破坏stack栈从栈顶到栈底元素依次减小的规律,故将3位置弹出栈,由于当前弹出的
* 位置是3位置,3位置再栈内的下一元素位置是2位置,所以res[3]={2,4};此时stack栈从栈顶到栈底的元素依次是{2位置(3),1位置(1)};
* 由于arr[4]==arr[2]==3,即为当前遍历到的位置对应的元素值与stack当前栈顶的元素对应初始数组位置值相同,所以将两个位置压在一起。
* 此时stack栈从栈顶到栈底的元素依次是{[2位置,4位置](3),1位置(1)};
*
* 6.遍历到arr[5]==5时,发现将5位置直接压入栈内不会破坏stack栈从栈顶到栈底元素依次减小的规律,故将5位置压入栈内,此时stack
* 栈从栈顶到栈底的元素依次是{5位置(5),[2位置,4位置](3),1位置(1)};
*
* 7.遍历到arr[6]==3时发现,此时stack栈顶元素是5位置,由于arr[5]>arr[6],故将6位置直接压入栈内会破坏stack栈从栈顶到栈底元
* 素依次减小的规律,故将5位置弹出栈,由于当前弹出的位置是5位置,5位置再栈内的下一元素位置是[2位置,4位置],选择最晚加入的4位置作为
* 比当前元素小且距离最近的位置,即为res[5]={4,6}。此时stack栈从栈顶到栈底的元素依次是{[2位置,4位置](3),1位置(1)};由于此时
* stack的栈顶元素是[2位置,4位置],由于arr[6]==arr[2]==arr[4]==3,即为当前遍历到的位置对应的元素值与stack当前栈顶的元素
* 对应初始数组位置值相同,所以将三个位置继续压在一起。此时stack栈从栈顶到栈底的元素依次是{[2位置,4位置,6位置](3),1位置(1)};
*
* 8.遍历到arr[7]==2时,发现此时stack栈顶元素是[2位置,4位置,6位置],由于arr[7]<arr[6]==arr[2]==arr[4]==3,故将7位置
* 直接压入栈内会破坏stack栈从栈顶到栈底元素依次减小的规律,故将[2位置,4位置,6位置]弹出栈,由于当前弹出的位置是[2位置,4位置,6位置],
* [2位置,4位置,6位置]再栈内的下一元素是位置1,因此res[2]={1,7},res[4]={1,7},res[6]={1,7}.此时stack栈从栈顶到栈底的元
* 素依次是{1位置(1)};此时将7位置压入栈内不会破坏stack栈从栈顶到栈底元素依次减小的规律,故将7位置压入栈内,此时stack栈从栈顶到栈底
* 的元素依次是{7位置(2),1位置(1)};
*
* 9.遍历到arr[8]==2时,此时stack的栈顶元素是位置7,由于arr[8]==arr[7]==2,即为当前遍历到的位置对应的元素值与stack当前栈顶的
* 元素对应初始数组位置值相同,所以将两个位置压在一起。此时stack栈从栈顶到栈底的元素依次是{[7位置,8位置](2),1位置(1)}。
*
* ************遍历结束************
* 10.遍历完成进入清算阶段
*
* ************清算阶段************
* 1.由于stack栈从栈顶到栈底的元素依次是{[7位置,8位置](2),1位置(1)},将栈顶元素弹出栈,即为弹出[7位置,8位置],由于[7位置,8位置]在
* 栈内的下一元素是1位置,同时由于是清算阶段弹出的元素,所以当前弹出元素的右边没有比当前元素小的元素。故res[7]={1,-1},res[8]={1,-1}。
* 此时stack栈从栈顶到栈底的元素依次是{1位置(1)};
* 2.由于stack栈从栈顶到栈底的元素依次是{1位置(1)},从栈内弹出1位置,此时栈stack为空,即为{}。由于1位置是清算阶段弹出的,
* 所以res[1]={-1,-1}。
*
* @author 雪瞳
*
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class getNearLessElements {
public int[][] getNearElements(int arr[]){
int length = arr.length;
int res[][] = new int[length][2];
int IndexElement = 0;
int popIndex = 0;
int leftElement = 0;
int rightElement = 0;
//将列表存储于栈内,相同位置元素存储于同一个列表内
Stack<List<Integer>> stack = new Stack<>();
for(int i=0;i<length;i++) {
IndexElement = arr[i];
//栈需要弹出元素
while(!stack.isEmpty() && arr[stack.peek().get(0)]>IndexElement) {
List<Integer> popList=stack.pop();
if(stack.isEmpty()) {
leftElement = -1;
}else {
//获取栈顶元素所返回的列表,选取最后加入的那个作为左边的位置
List<Integer> tip = stack.peek();
leftElement = tip.get(tip.size()-1);
}
//遍历弹出的列表
for(int j=0;j<popList.size();j++) {
popIndex = popList.get(j);
res[popIndex][0]=leftElement;
res[popIndex][1]=i;
}
}
//栈不需要弹出元素
//当栈顶元素和当前遍历元素所对应的数组值相同
if(!stack.isEmpty() && arr[stack.peek().get(0)]==IndexElement) {
//将i转化成Integer类型并存入到栈顶列表内
stack.peek().add(Integer.valueOf(i));
}else {
//不同则直接将当前遍历位置存入列表并压入栈内
List<Integer> ls = new ArrayList<Integer>();
ls.add(Integer.valueOf(i));
stack.push(ls);
}
}
//清算阶段
while(!stack.isEmpty()) {
List<Integer> list = stack.pop();
//获取leftElement元素
if(!stack.isEmpty()) {
List<Integer> ls = stack.peek();
leftElement = ls.get(ls.size()-1);
}else {
leftElement = -1;
}
//遍历列表
for(int i=0;i<list.size();i++) {
popIndex = list.get(i);
res[popIndex][0]=leftElement;
res[popIndex][1]=-1;
}
}
return res;
}
public void showElements(int array[][]) {
for(int arr[]:array) {
for(int element:arr) {
System.out.print(element+"\t");
}
System.out.println();
}
}
}
import java.util.Random;
import java.util.Scanner;
public class testGetNearElements {
public static void main(String[] args) {
getNearLessElements test = new getNearLessElements();
testGetNearElements show = new testGetNearElements();
Scanner sc = new Scanner(System.in);
Random rand = new Random();
System.out.println("please input the array length");
int len = sc.nextInt();
int arr[]=new int[len];
for(int i=0;i<len;i++) {
arr[i]=(rand.nextInt(10)+1);
}
show.showArray(arr);
int res[][]=new int[arr.length][2];
res = test.getNearElements(arr);
test.showElements(res);
}
public void showArray(int array[]) {
for(int element :array) {
System.out.print(element+"\t");
}
System.out.println();
}
}
标签:类型 add 变化 分析 入栈 数组 print java ret
原文地址:https://www.cnblogs.com/walxt/p/12455188.html