数据结构-随看-栈-补
-
栈:先入后出, push pop。
-
模板: Stack<Integer> s = new Stack<>(); s.push(); s.pop();
-
最小栈
设计一个支持 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:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: 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;
}
}
}
-
栈和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); }
-
克隆图
给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。
图中的每个节点都包含它的值
val
(int
) 和其邻居的列表(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; }
-
-