開一個n的區間, 指針指向開頭; 不夠的時候, 再開一個2n的區間, 把指針挪過來.node
FIFO隊列包含兩個基本操做:插入(put)一個新的項,刪除(get)一個最先插入的項。算法
循環數組實現方式:express
對於每個隊列數據結構,咱們保留一個數組S,其最多存放的Nmax個元素,定義兩個位置front和rear分別指向隊列的頭尾兩端,此外咱們用N來記錄隊列中實際存在的元素 的個數。編程
對於一個元素item入隊,咱們讓N和rear增1,而後置s[rear]=item; 對於一個元素item入隊,咱們讓N減1,讓front增1.
注意:這種實現有一個潛在的問題。假設數組的Nmax=10,通過10次入隊後,隊列彷佛已經滿了,由於此時rear=9.然而,隊列中可能只存在小於9個的元素,由於 以前入隊的操做可能伴隨着出隊的操做。例如咱們將1,2,3,4,5,6,7,8,9,10一次入隊,而後又進行2次出隊操做,此時front指向數組元素S[2]處的位置,此時隊列中只 有8個元素,這時rear仍然指向數組的最後一個元素S[Nmax-1]的位置,此時咱們有沒有辦法繼續進行入隊操做呢?數組
簡單的解決方法是:只要front和rear到達數組的末尾,它就又繞回到開頭,這種實現方式就是循環數組的實現。這樣隊列的操做就侷限在所定義的數組這塊存儲空間內。網絡
push, pop, top數據結構
push, pop,front,backapp
Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).ide
將「內存」中結構化的數據變成「字符串」的過程wordpress
序列化:object to string
反序列化:string to object
Example
An example of testdata: Binary tree {3,9,20,#,#,15,7}
, denote the following structure:
3 / \ 9 20 / \ 15 7
class Solution { /** * This method will be invoked first, you should design your own algorithm * to serialize a binary tree which denote by a root node to a string which * can be easily deserialized by your own "deserialize" method later. */ public String serialize(TreeNode root) { if (root == null) { return "{}"; } ArrayList<TreeNode> queue = new ArrayList<TreeNode>(); queue.add(root); for (int i = 0; i < queue.size(); i++) { TreeNode node = queue.get(i); if (node == null) { continue; } queue.add(node.left); queue.add(node.right); } while (queue.get(queue.size() - 1) == null) { queue.remove(queue.size() - 1); } StringBuilder sb = new StringBuilder(); sb.append("{"); sb.append(queue.get(0).val); for (int i = 1; i < queue.size(); i++) { if (queue.get(i) == null) { sb.append(",#"); } else { sb.append(","); sb.append(queue.get(i).val); } } sb.append("}"); return sb.toString(); } /** * This method will be invoked second, the argument data is what exactly * you serialized at method "serialize", that means the data is not given by * system, it's given by your own serialize method. So the format of data is * designed by yourself, and deserialize it here as you serialize it in * "serialize" method. */ public TreeNode deserialize(String data) { if (data.equals("{}")) { return null; } String[] vals = data.substring(1, data.length() - 1).split(","); ArrayList<TreeNode> queue = new ArrayList<TreeNode>(); TreeNode root = new TreeNode(Integer.parseInt(vals[0])); queue.add(root); int index = 0; boolean isLeftChild = true; for (int i = 1; i < vals.length; i++) { if (!vals[i].equals("#")) { TreeNode node = new TreeNode(Integer.parseInt(vals[i])); if (isLeftChild) { queue.get(index).left = node; } else { queue.get(index).right = node; } queue.add(node); } if (!isLeftChild) { index++; } isLeftChild = !isLeftChild; } return root; } }
Given n
nodes labeled from 0
to n - 1
and a list of undirected
edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
一個graph是否是tree的決定條件有兩個:
public class Solution { /** * @param n an integer * @param edges a list of undirected edges * @return true if it's a valid tree, or false */ public boolean validTree(int n, int[][] edges) { if (n == 0) { return false; } if (edges.length != n - 1) { return false; } Map<Integer, Set<Integer>> graph = initializeGraph(n, edges); // bfs Queue<Integer> queue = new LinkedList<>(); Set<Integer> hash = new HashSet<>(); queue.offer(0); hash.add(0); while (!queue.isEmpty()) { int node = queue.poll(); for (Integer neighbor : graph.get(node)) { if (hash.contains(neighbor)) { continue; } hash.add(neighbor); queue.offer(neighbor); } } return (hash.size() == n); } private Map<Integer, Set<Integer>> initializeGraph(int n, int[][] edges) { Map<Integer, Set<Integer>> graph = new HashMap<>(); for (int i = 0; i < n; i++) { graph.put(i, new HashSet<Integer>()); } for (int i = 0; i < edges.length; i++) { int u = edges[i][0]; int v = edges[i][1]; graph.get(u).add(v); graph.get(v).add(u); } return graph; } }
Clone an undirected graph. Each node in the graph contains a label
and a list of its neighbors
.
How we serialize an undirected graph:
Nodes are labeled uniquely.
We use #
as a separator for each node, and ,
as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}
.
The graph has a total of three nodes, and therefore contains three parts as separated by #
.
0
. Connect node 0
to both nodes 1
and 2
.1
. Connect node 1
to node 2
.2
. Connect node 2
to node 2
(itself), thus forming a self-cycle.Visually, the graph looks like the following:
1 / \ / \ 0 --- 2 / \ \_/
public class Solution { /** * @param node: A undirected graph node * @return: A undirected graph node */ public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if (node == null) { return node; } // use bfs algorithm to traverse the graph and get all nodes. ArrayList<UndirectedGraphNode> nodes = getNodes(node); // copy nodes, store the old->new mapping information in a hash map HashMap<UndirectedGraphNode, UndirectedGraphNode> mapping = new HashMap<>(); for (UndirectedGraphNode n : nodes) { mapping.put(n, new UndirectedGraphNode(n.label)); } // copy neighbors(edges) for (UndirectedGraphNode n : nodes) { UndirectedGraphNode newNode = mapping.get(n); for (UndirectedGraphNode neighbor : n.neighbors) { UndirectedGraphNode newNeighbor = mapping.get(neighbor); newNode.neighbors.add(newNeighbor); } } return mapping.get(node); } private ArrayList<UndirectedGraphNode> getNodes(UndirectedGraphNode node) { Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>(); HashSet<UndirectedGraphNode> set = new HashSet<>(); queue.offer(node); set.add(node); while (!queue.isEmpty()) { UndirectedGraphNode head = queue.poll(); for (UndirectedGraphNode neighbor : head.neighbors) { if(!set.contains(neighbor)){ set.add(neighbor); queue.offer(neighbor); } } } return new ArrayList<UndirectedGraphNode>(set); } }
三步走:
勸分不勸合, 編程能分開的儘可能分開寫。
能用BFS, 必定不用DFS, 由於dfs有recursion, 容易stack over flow
由點及面
不用作分層遍歷
Given a undirected graph
, a node
and a target
, return the nearest node to given node which value of it is target, return NULL
if you can’t find.
There is a mapping
store the nodes’ values in the given parameters.
It’s guaranteed there is only one available solution
2------3 5 \ | | \ | | \ | | \ | | 1 --4 Give a node 1, target is 50 there a hash named values which is [3,4,10,50,50], represent: Value of node 1 is 3 Value of node 2 is 4 Value of node 3 is 10 Value of node 4 is 50 Value of node 5 is 50 Return node 4
public class Solution { /** * @param graph a list of Undirected graph node * @param values a hash mapping, <UndirectedGraphNode, (int)value> * @param node an Undirected graph node * @param target an integer * @return the a node */ public UndirectedGraphNode searchNode(ArrayList<UndirectedGraphNode> graph, Map<UndirectedGraphNode, Integer> values, UndirectedGraphNode node, int target) { // Write your code here Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>(); Set<UndirectedGraphNode> hash = new HashSet<UndirectedGraphNode>(); queue.offer(node); hash.add(node); while (!queue.isEmpty()) { UndirectedGraphNode head = queue.poll(); if (values.get(head) == target) { return head; } for (UndirectedGraphNode nei : head.neighbors) { if (!hash.contains(nei)){ queue.offer(nei); hash.add(nei); } } } return null; } }
-能夠用DFS?
能夠,可是不推薦
-應用場景
選課
編譯:編譯的時候用link的東西,因此要看看有沒有循環依賴。
-關心可否進行拓撲排序, 便是關心有沒有環
-入度: 指向一個節點的邊的個數
Given an directed graph, a topological order of the graph nodes is defined as follow:
A -> B
in graph, A must before B in the order list.Find any topological order for the given graph.
For graph as follow:
The topological order can be:
[0, 1, 2, 3, 4, 5] [0, 2, 3, 1, 5, 4] ...
There are a total of n courses you have to take, labeled from 0
to n - 1
.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
Given n = 2
, prerequisites = [[1,0]]
Return true
Given n = 2
, prerequisites = [[1,0],[0,1]]
Return false