109
109
- [ Graph] ( #graph )
110
110
- [ Edge list vs Adjacent list vs Adjacent matrix] ( #edge-list-vs-adjacent-list-vs-adjacent-matrix )
111
111
- [ Build graph] ( #build-graph )
112
+ - [ Detect cycles inside undirected graph] ( #detect-cycles-inside-undirected-graph )
113
+ - [ Detect cycles inside directed graph] ( #detect-cycles-inside-directed-graph )
112
114
- [ Trie] ( #trie )
113
115
- [ Use case] ( #use-case-1 )
114
116
- [ Trie definition] ( #trie-definition )
169
171
- [ Memorization array tricks] ( #memorization-array-tricks )
170
172
- [ Type] ( #type )
171
173
- [ Online IDE templates] ( #online-ide-templates )
174
+ - [ Coderpad] ( #coderpad )
172
175
- [ References] ( #references )
173
176
174
177
<!-- /MarkdownTOC -->
@@ -1827,7 +1830,6 @@ class SegmentTreeNode
1827
1830
* Validate binary search tree
1828
1831
- Iterative inorder traversal, current node > successor (stack top). Works for BST with no duplication constraints
1829
1832
- Divide and conquer, pass down value range in children nodes
1830
- * Kth node in a BST
1831
1833
1832
1834
* Generic tree preorder/inorder/postorder iterative traversal with O(logn) space. Three types of implementation could be changed with minimal code change.
1833
1835
```java
@@ -2200,8 +2202,82 @@ public Map<Integer, Set<Integer>> buildGraph( int n, int[][] edges )
2200
2202
}
2201
2203
}
2202
2204
```
2203
- * ** Detect cycles inside undirected graph** with dfs + discovered set.
2204
- * ** Detect cycles inside directed graph** with dfs + visited set + discovered set.
2205
+
2206
+ ##### Detect cycles inside undirected graph
2207
+
2208
+ ``` java
2209
+ // Graph is represented by class GraphNode
2210
+ class GraphNode
2211
+ {
2212
+ int nodeIndex;
2213
+ List<GraphNode > neighbors;
2214
+ }
2215
+
2216
+ private boolean hasCycle( GraphNode root )
2217
+ {
2218
+ return hasCycle( root, new HashSet<> () );
2219
+ }
2220
+
2221
+ private boolean hasCycle( GraphNode root, Set<GraphNode > isDiscovered )
2222
+ {
2223
+ if ( isDiscovered. contains( root ) )
2224
+ {
2225
+ return true ;
2226
+ }
2227
+
2228
+ isDiscovered. add( root );
2229
+ for ( List<GraphNode > neighbor : root. neighbors )
2230
+ {
2231
+ if ( hasCycle( neighbor, isVisited ) )
2232
+ {
2233
+ return true ;
2234
+ }
2235
+ }
2236
+
2237
+ return false ;
2238
+ }
2239
+ ```
2240
+
2241
+ ##### Detect cycles inside directed graph
2242
+
2243
+ ``` java
2244
+ // Graph is represented by class GraphNode
2245
+ class GraphNode
2246
+ {
2247
+ int nodeIndex;
2248
+ List<GraphNode > neighbors;
2249
+ }
2250
+
2251
+ private boolean hasCycle( GraphNode root )
2252
+ {
2253
+ Set<GraphNode > isDiscovered = new HashSet<> ();
2254
+ Set<GraphNode > isVisited = new HashSet<> ();
2255
+ return hasCycle( root, isDiscovered, isVisited );
2256
+ }
2257
+
2258
+ private boolean hasCycle( GraphNode root, Set<GraphNode > isDiscovered, Set<GraphNode > isVisited )
2259
+ {
2260
+ if ( isVisited. contains( root ) )
2261
+ {
2262
+ return false ;
2263
+ }
2264
+ if ( isDiscovered. contains( root ) && ! isVisited. contains( root ) )
2265
+ {
2266
+ return true ;
2267
+ }
2268
+
2269
+ isDiscovered. add( root );
2270
+ for ( List<GraphNode > neighbor : root. neighbors )
2271
+ {
2272
+ if ( hasCycle( neighbor, isDiscovered, isVisited ) )
2273
+ {
2274
+ return true ;
2275
+ }
2276
+ }
2277
+ isVisited. add( root );
2278
+ return false ;
2279
+ }
2280
+ ```
2205
2281
2206
2282
#### Trie
2207
2283
##### Use case
@@ -2803,6 +2879,7 @@ public int binarySearchRecursive( int[] array, int target, int start, int end )
2803
2879
+ If multiple results are of same type, define return type as an array T[ ]
2804
2880
+ If only two results are returned, consider using AbstractMap.SimpleEntry<K,V>
2805
2881
+ Define a result wrapper class
2882
+
2806
2883
``` java
2807
2884
// 1. not use use global variables
2808
2885
// 1.1. global variables as class instance
@@ -2838,6 +2915,7 @@ private class ResultWrapper
2838
2915
2839
2916
##### Avoid duplicated recursion
2840
2917
* ensuring that the never two recursion tree branches overlap
2918
+
2841
2919
``` java
2842
2920
if ( i > 0 && candidates[i] == candidates[i- 1 ] )
2843
2921
{
@@ -2846,6 +2924,7 @@ if ( i > 0 && candidates[i] == candidates[i-1] )
2846
2924
}
2847
2925
// invoking functions based on index i
2848
2926
```
2927
+
2849
2928
##### Types
2850
2929
2851
2930
* Tree-based recursion
@@ -2880,8 +2959,6 @@ public ResultWrapper secondApproach( TreeNode currNode )
2880
2959
- Key points: Use a hashmap to store old to new reference mapping
2881
2960
- Examples: Clone graph, Copy list with random pointer
2882
2961
2883
- * Array-based recursion
2884
-
2885
2962
#### Backtrack
2886
2963
##### Best practices
2887
2964
* There are two popular ways to keep track of traverse path
@@ -3349,7 +3426,7 @@ public int houseRobber_RollingArray( int[] A )
3349
3426
+ Examples: Backpack I-VI (Lintcode), K Sum (Lintcode), Minimum adjustment cost (Lintcode)
3350
3427
3351
3428
### Online IDE templates
3352
- * Coderpad
3429
+ #### Coderpad
3353
3430
3354
3431
``` java
3355
3432
import org.junit.* ;
0 commit comments