zoukankan      html  css  js  c++  java
  • 每日一题 为了工作 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();
        }
    }
  • 相关阅读:
    hadoop配置文件说明
    hadoop集群部署
    Linux iptables防火墙实用模板
    不容忽视的SQL注入式攻击
    字符串的加解密
    .NET程序集版本号的奥秘
    SQL Server 2005 数据库引擎的容量规范
    Microsoft Visual Studio Tools for the Microsoft Office system(3.0 版)
    How to: Display a Dialog Box for Selecting Entries from the Contacts Folder
    OpenID及其原理介绍
  • 原文地址:https://www.cnblogs.com/walxt/p/12455188.html
Copyright © 2011-2022 走看看