数据结构-随看-栈-补

数据结构-随看-栈-补

  1. 栈:先入后出, push pop

  2. 模板:
        Stack<Integer> s = new Stack<>();
    	s.push();
    	s.pop();
    
  3. 最小栈

设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) – 将元素 x 推入栈中。
  • pop() – 删除栈顶的元素。
  • top() – 获取栈顶元素。
  • getMin() – 检索栈中的最小元素。

示例:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

code

class MinStack{
    //initialize
    Stack<Integer> min;
    Stack<Integer> stack;
    
    public MinStack(){
        stack = new Stack<Integer>();
        min = new Stack<Integer>();
    }
    
    public void push(int x){
        stack.push(x);
        if(min.empty()){
            min.push(x);
        }else{
            if(x <= min.peek()){//keep min element always on top
                min.push(x);
            }
        }
    }
    
    public void pop(){
        if(min.peek().equals(stack.peek())){
            min.pop;
        }
        if(!stack.empty()){
            stack.pop();
        }else
            throw new RuntimeException("-1");
    }
    public int top(){
        if(!stack.empty()){
            return stack.peek();
        }else
            throw new RuntimeException("-1");
    }
    public int getMin(){
        if(!min.empty()){
            return min.peek();
        }else
            throw new RuntimeException("-1");
    }
}
  1. 有效的括号

    给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true

示例 2:

扫描二维码关注公众号,回复: 9946083 查看本文章
输入: "()[]{}"
输出: true

示例 3:

输入: "(]"
输出: false

示例 4:

输入: "([)]"
输出: false

示例 5:

输入: "{[]}"
输出: true

code

class Solution{
    public boolean isValid(String s){
        HashMap<Character, Character> map = new HashMap<>();
        map.put(')','(');//进行配对
        map.put('}','{');
        map.put(']','[');
        Stack<Character> stack = new Stack<>();
        for(int i = 0;i<s.length();i++){
            if((s.charAt(i) == ' ')){
                continue;
            }else if(stack.isEmpty()||stack.peek() != map.get(s.charAt(i))){
                stack.push(s.charAt(i));
            }else{
                stack.pop();
            }
        }
        if(stack.isEmpty()){
            return true;
        }else{
            return false;
        }
    }
}
  1. 栈和DFS

    • 在我们到达最深的节点之后,我们会回溯并尝试另一条路径。

    • 当我们回溯时,我们将从栈中弹出最深的结点,实际上就是推到栈中的最后一个结点。

    • 结点的处理顺序完全相反,就像是被添加到栈中一样。

    • DFS-模板|

      • 递归

      • //return true if there is a path from cur to target
        boolean DFS(Node cur, Node target, Set<Node> visited){
            return true if cur is target;
            for(next:each neighbor of cur){
                if(next is not in visited){
                    add next to visited;
                    return true if DFS(next,target,visited) == true;
                }
            }
            return false;
        }
        
      • 岛屿数量(DFS): 从一个为1的根节点开始访问,从每个相邻1结点下访问到顶点依次访问其他相邻结点到顶点。

      • public int numIslands(char[][] grid){
            if(grid == null || grid.length == 0) return 0;
            int row = grid.lenght, column = grid[0].length,count=0;//和string不一样长度length,length()
            for(int i=0;i<row;i++){
                for(int j=0;j<column;j++){
                    if(grid[i][j] == '1'){
                        dfs(grid,i,j,row,column);
                        count++;
                    }
                }
            }
            return count;
        }
        
        private void dfs(char[][] grid, int i, int j, int row, int column){
            if(i<0||j<0||i>=row||j>=column || grid[i][j] == '0') return;
            grid[i][j] = '0';
            dfs(grid,i+1,j,row,column);
            dfs(grid,i,j+1,row,column);
            dfs(grid,i-1,j, row ,column);
            dfs(grid,i,j-1,row,column);
        }
        
      • 克隆图

        给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。

        图中的每个节点都包含它的值 valint) 和其邻居的列表(list[Node])。

        class Node {
            public int val;
            public List<Node> neighbors;
        }
        

        思路:首先对图进行一个遍历,把所有的节点new出来,不处理neighbors,并且把所以节点存到map中。之后再进行更新neighbors

        code BFS

        public Node cloneGraph(Node node){
            if(node == null){
                return node;
            }
            Queue<Node> queue = new LinkedList<>();
            Map<Integer, Node> map = new HashMap<>();
            queue.offer(node);
            Node n = new Node();
            n.val = node.val;
            n.neighbors = new ArrayList<Node>();
            map.put(n.val,n);
            while(!queue.isEmpty()){
                Node cur = queue.poll();
                for(Node temp : cur.neighbors){
                    if(!map.containsKey(temp.val)){
                        n = new Node();
                        n.val = temp.val;
                        n.neighbors = new ArrayList<>();
                        map.put(n.val,n);
                        queue.offer(temp);
                    }//更新neighbors
                    map.get(cur.val).neighbor.add(map.get(temp.val));
                }
            }
            return map.get(node.val);
        }
        

        DFS

        public Node cloneGraph(Node node){
            if(node == null){
                return node;
            }
            Map<Integer,Node> map = new HashMap<>();
            return cloneGraphHelper(node,map);
        }
        private Node cloneGraphHelper(Node node,Map<Integer,Node> map){
            if(map.containsKey(node.val)){
                return map.get(node.val);
            }
            //生成当前节点
            Node n = new Node();
            n.val = node.val;
            n.neighbors = new ArrayList<>();
            map.put(node.val, n);
            //添加它的所有邻居节点
            for(Node temp : node.neighbors){
                n.neighbors.add(cloneGraphHelper(temp,map));
            }
            return n;
        }
        
      • DFS-模板||

      • 递归解决方案的优点是它更容易实现。 但是,存在一个很大的缺点:如果递归的深度太高,你将遭受堆栈溢出。 在这种情况下,您可能会希望使用 BFS,或使用显式栈实现 DFS。

      • /*
         * Return true if there is a path from cur to target.
         */
        boolean DFS(int root, int target) {
            Set<Node> visited;
            Stack<Node> s;
            add root to s;
            while (s is not empty) {
                Node cur = the top element in s;
                return true if cur is target;
                for (Node next : the neighbors of cur) {
                    if (next is not in visited) {
                        add next to s;
                        add next to visited;
                    }
                }
                remove cur from s;
            }
            return false;
        }
        
      • 二叉树的中序遍历

      • code 递归

      • class Solution{
            public List<Integer> inorderTraversal(TreeNode root){
                List<Integer> res = new ArrayList<>();
                helper(root,res);
                return res;
            }
            
            public void helper(TreeNode root, List<Integer> res){
                if(root != null){
                    if(root.left != null){
                        helper(root.left,res);
                    }
                    res.add(root.val);
                	if(root.right != null){
                    	helper(root.right,res)
                	}
                }
            }
        }
        
      • code Stack

      • public list<Integer> inorderTraversal(TreeNode root){
            List<Integer> res = new ArrayList<>();//存放遍历的结果
            Stack<TreeNode> stack = new Stack<>();//中间存放
            TreeNode curr = root;
            while(curr != null || !stack.isEmpty()){
                while(curr != null){
                    stack.push(curr);
                    curr = curr.left;
                }
                curr = stack.pop();
                res.add(curr.val);
                curr = curr.right;
            }
            return res;
        }
        
发布了94 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_31900497/article/details/104308687