每日一题 为了工作 2020 03010 第八题

Posted walxt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一题 为了工作 2020 03010 第八题相关的知识,希望对你有一定的参考价值。

/**
* 题目: 第七题的进阶问题
* 给定一个可能含重复值的数组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+"	");
            }
            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+"	");
        }
        System.out.println();
    }
}

 

以上是关于每日一题 为了工作 2020 03010 第八题的主要内容,如果未能解决你的问题,请参考以下文章

每日一题 为了工作 2020 0510 第六十八题

每日一题 为了工作 2020 0502 第六十一题

每日一题 为了工作 2020 0303 第一题

每日一题 为了工作 2020 0323 第二十一题

每日一题 为了工作 2020 03019 第十七题

每日一题 为了工作 2020 0508 第六十六题