数据结构与算法-栈

1,158 阅读2分钟

1,什么是栈?

  • 是一种特殊的线性表,只能在一端进行操作
  • 往栈中 添加 元素的操作,一般叫做 push,入栈
  • 从栈中 移除 元素的操作,一般叫做 pop,出栈
  • 栈 又有 栈底栈顶。一般最先压栈的就是 栈底元素,在最后压栈的就是 栈顶元素
  • 栈 遵循 先进后出 的原则, Last in first out, LIFO

2,栈的实现

  • 用动态数组的形式来实现 栈

动态数组的具体实现请查看 数据结构与算法-动态数组

public class Stack<E> {    
    //创建动态数组    
    private List<E> list = new ArrayList<>();        
    //清除栈内元素   
     public void clear() {        
        //调用 ArrayList的clear方法        
        list.clear();    
    }        
    
    //获取栈内元素 数量    
    public int size() {        
        //调用 ArrayList的size方法        
        return list.size();    
    }

    //判断栈是否为空    
    public boolean isEmpty() {        
        //调用 ArrayList的isEmpty方法        
        return list.isEmpty();    
    }

    //压栈    
    public void push(E element) {        
        //就是ArrayList添加 元素        
        list.add(element);    
    }

    //出栈    
    public E pop() {        
        //就是从ArrayList的最末尾删除元素        
        return list.remove(list.size() - 1);    
    }

    //获取栈底元素    
    public E top() {        
        //就是获取ArrayList的最末尾的元素        
        return list.get(list.size() - 1);    
    }
}

3,栈的应用

  • 浏览器的前进和后退

  • 图片修图的撤销和还原的实现

原理:会创建两个栈A和B,一个是为了记录压栈顺序A,一个记录出栈的顺序B。

1,当我们浏览网页时,一次打开 baibu.com - taobao.com - qq.com。依次压入栈A

2,当我们后退时,就从栈A中pop出来,依次把 qq.com - taobao.com 。依次压入栈B。

3,在前进时,就从栈B中pop出来,压入栈A。

4,当再次有新的网页jd.com打开时,把jd.com压入栈A,同时清空栈B

4,leetCode算法题练习

4.1,leetCode算法题--20. 有效的括号

面试题链接:leetcode-cn.com/problems/va…

面试题分析:从题目我们可以看出,当输入为" [ ] { } ( ) " , " { [ ( ) ] }"时,是有效括号。

解法一:比较法

解体思路:当string里面包含" [] " , " () " , " {} " 时,就把它替换为空字符。最后string长度为空时,说明匹配有效。 

class Solution {    
    public boolean isValid(String s) {        
        while (s.contains("[]") || s.contains("()") || s.contains("{}") ){            
            s = s.replace("[]","");            
            s = s.replace("()","");            
            s = s.replace("{}","");        
        }        
        return s.isEmpty();    
    }
}

解法二:栈

解体思路:我们可以用栈来实现。
1, " {  " ,"  [ " , " ( " ,我们称为左字符。" } " , " ] " , " ) "我们称为右字符
2,当我们遇到左字符的时候就,压栈。当遇到右字符的时候,就取出栈顶元素跟右字符比较。匹配是有效字符就弹出栈顶,不匹配是无效字符。
3,遇到右字符就依次跟栈顶比较,pop栈顶元素,最后比较完,栈为空为有效字符。否则为无效字符。

class Solution {    
    public boolean isValid(String s) {        
        //创建 栈        
        Stack<Character> stack = new Stack<>();        
        //获取string的长度        
        int len = s.length();        
        //遍历string里面的每个字符        
        for (int i = 0; i < len; i ++){            
            //获取每个字符            
            char c = s.charAt(i);            
            //如果是左括号            
            if (c == '[' || c == '(' || c == '{') {                
                //压栈                
                stack.push(c);            
            } else {                
                //如果是右括号                
                //如果栈为空,没有左括号,不匹配                
                if (stack.isEmpty()) return false;                
                //取出栈顶元素(左括号)                
                char left = stack.pop();                
                //左括号和右括号不匹配                
                if (left == '[' && c != ']') return false;                
                if (left == '(' && c != ')') return false;                
                if (left == '{' && c != '}') return false;            
            }        
        }        
        //栈为空,左括号与右括号匹配        
        return stack.isEmpty();    
    }
}