栈
什么叫做栈:
在数据结构里,后进先出(LIFO)先出顺序。例如一摞叠在一起的盘子:存盘子的时候,从下往上一个一个放;取的时候,从上往下一个一个依次取。
栈既可以用数组来实现,也可以用链表来实现。
用数组实现的栈,叫顺序栈,用链表实现的栈,叫链式栈。
public class ArrayStack { private String[] items; private int count; // 栈中元素个数 private int n; //栈大小 //初始化,申请一个大小为n的数组 public ArrayStack(int n) { this.items = new String[n]; this.n = n; this.count = 0; } // 入栈操作 public boolean push(String item) { // 数组空间不够了,直接返回false,入栈失败。 if (count == n) return false; // 将item放到下标为count的位置,并且count加一 items[count] = item; ++count; return true; } // 出栈操作 public String pop() { // 栈为空,则直接返回null if (count == 0) return null; // 返回下标为count-1的数组元素,并且栈中元素个数count减一return items[--count]; } }
例题:判断字符串括号是否合法
字符串中只有字符'('和')'。合法字符串需要括号可以配对。例如:
输入:"()"
输出:true
实现一个函数,来判断给定的字符串是否合法。
public boolean isValied(String s){ //长度为空 if(s==null){ return true; } //长度不是偶数 if (s.length()%2==1){ return false; } Stack<Character> stack = new Stack<>(); for(int i = 0; i< s.length();i++){ Character c = s.charAt(i); if(c =='('){ stack.push(c); }else if(c == ')'){ if (stack.isEmpty() ){ return false; } stack.pop(); }else { return false; } } return stack.isEmpty(); }
例:大鱼吃小鱼
在水中有许多鱼,可以认为这些鱼停放在 x 轴上。
给定两个数组 Size,Dir,Size[i] 表示第 i 条鱼的大小,Dir[i] 表示鱼的方向 (0 表示向左游,1 表示向右游),并且两个数组的长度相等。
鱼的行为符合以下条件:
所有的鱼都同时开始游动,每次按照鱼的方向,都游动一个单位距离;
当方向相对时,大鱼会吃掉小鱼;
鱼大小都不相同。
输入:Size = [4, 2, 5, 3, 1], Dir = [1, 1, 0, 0, 0]
输出:3
请完成以下接口来计算还剩下几条鱼?
int getLeftFish(int[] fishSize, int[] fishDirection){ int finshNumber = fishSize.length; if (finshNumber<=1){ return finshNumber; } final int left = 0; final int right = 1; Stack<Integer> stack = new Stack<>(); for (int i = 0; i < stack.size(); i++){ boolean eat = false; final int curDirection = fishDirection[i]; final int curSize = fishSize[i]; while (stack.isEmpty()!=true && fishDirection[stack.peek()]== right && curDirection ==left){ if(fishSize[stack.peek()]>curSize){ eat = true; break; } stack.pop(); } if (eat != true){ stack.push(i); } } return stack.size(); }
例:找出数组中右边比我小的元素
一个整数数组 A,找到每个元素:右边第一个比我小的下标位置,没有则用 -1 表示。
用递增栈
int[] findRightSmall(int[] A){ int [] right = new int[A.length]; Stack<Integer> stack = new Stack<>(); for (int i = 0; i < A.length; i++){ while (!stack.isEmpty()&&A[stack.peek()]>A[i]){ right[stack.peek()]=i; t.pop(); } stack.push(i); } while (!stack.isEmpty()){ right[stack.pop()]=-1; } return right; }
例 :字典序最小的 k 个数的子序列
int[] findSmallSeq(int[] A, int k){ int [] ans = new int[k]; Stack<Integer> stack = new Stack<>(); for (int i = 0; i < A.length; i++){ while(!stack.isEmpty() &&stack.size()+ A.length - i >k && stack.peek()>A[i]){ stack.pop(); } stack.push(A[i]); } while (stack.size()>k){ stack.pop(); } for(int i = k - 1; i >= 0 ;i--){ ans[i] = stack.pop(); } return ans; }