Skip to content

Commit 3025b00

Browse files
committed
gou
1 parent 61b9c35 commit 3025b00

26 files changed

+3753
-2201
lines changed

Java/Bus Routes.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
H
2+
1534208810
3+
tags: BFS
4+
5+
```
6+
/*
7+
We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever.
8+
For example if routes[0] = [1, 5, 7], this means that the first bus (0-th indexed)
9+
travels in the sequence 1->5->7->1->5->7->1->... forever.
10+
11+
We start at bus stop S (initially not on a bus), and we want to go to bus stop T.
12+
Travelling by buses only, what is the least number of buses we must take to reach our destination?
13+
Return -1 if it is not possible.
14+
15+
Example:
16+
Input:
17+
routes = [[1, 2, 7], [3, 6, 7]]
18+
S = 1
19+
T = 6
20+
Output: 2
21+
Explanation:
22+
The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6.
23+
Note:
24+
25+
1 <= routes.length <= 500.
26+
1 <= routes[i].length <= 500.
27+
0 <= routes[i][j] < 10 ^ 6.
28+
*/
29+
30+
/*
31+
1. Map stop -> bus list
32+
2. Add stop to queue
33+
3. process queue, if stop match return; otherwise, try the linked bus (track visited bus)
34+
*/
35+
class Solution {
36+
public int numBusesToDestination(int[][] routes, int S, int T) {
37+
Set<Integer> visited = new HashSet<>();
38+
Map<Integer, Set<Integer>> stopMap = new HashMap<>();
39+
Queue<Integer> queue = new LinkedList<>();
40+
// init
41+
for (int i = 0; i < routes.length; i++) {
42+
for (int stop : routes[i]) {
43+
stopMap.putIfAbsent(stop, new HashSet<>());
44+
stopMap.get(stop).add(i); // add bus route to stop
45+
}
46+
}
47+
queue.offer(S);
48+
int count = 0;
49+
while (!queue.isEmpty()) {
50+
int size = queue.size();
51+
for (int i = 0; i < size; i++) {
52+
int stop = queue.poll(); // 1, 2, 7
53+
if (stop == T) return count;
54+
for (int bus : stopMap.get(stop)) {
55+
if (!visited.contains(bus)) {
56+
visited.add(bus);
57+
for (int nextStop : routes[bus]) {
58+
queue.offer(nextStop); // 3, 6, 7
59+
}
60+
}
61+
}
62+
}
63+
count++;
64+
}
65+
66+
return -1;
67+
}
68+
}
69+
```

Java/Cracking the Safe.java

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
H
2+
1534220198
3+
tags: Math, DFS, Greedy
4+
5+
#### Greedy, Iterative
6+
- For 2 passwords, the shortest situation is both passwords overlap for n-1 chars.
7+
- We can use a window to cut out last (n-1) substring and append with new candidate char from [k-1 ~ 0]
8+
- Track the newly formed string; if new, add the new char to overall result
9+
- Note: this operation will run for k^n times: for all spots of [0 ~ n - 1] each spot tries all k values [k-1 ~ 0]
10+
- Same concept as dfs
11+
12+
#### DFS
13+
- Same concept: use window to cut out tail, and append with new candidate
14+
- do this for k^n = Math.pow(k, n) times
15+
16+
```
17+
/*
18+
There is a box protected by a password. The password is n digits,
19+
where each letter can be one of the first k digits 0, 1, ..., k-1.
20+
21+
You can keep inputting the password,
22+
the password will automatically be matched against the last n digits entered.
23+
24+
For example, assuming the password is "345", I can open it when I type "012345",
25+
but I enter a total of 6 digits.
26+
27+
Please return any string of minimum length that is guaranteed to open the box
28+
after the entire string is inputted.
29+
30+
Example 1:
31+
Input: n = 1, k = 2
32+
Output: "01"
33+
Note: "10" will be accepted too.
34+
Example 2:
35+
Input: n = 2, k = 2
36+
Output: "00110"
37+
Note: "01100", "10011", "11001" will be accepted too.
38+
Note:
39+
n will be in the range [1, 4].
40+
k will be in the range [1, 10].
41+
k^n will be at most 4096.
42+
43+
http://www.cnblogs.com/grandyang/p/8452361.html
44+
*/
45+
46+
/*
47+
For 2 passwords, the shortest situation is both passwords overlap for n-1 chars.
48+
We can use a window to cut out last (n-1) substring and append with new candidate char from [k-1 ~ 0]
49+
Track the newly formed string; if new, add the new char to overall result
50+
Note: this operation will run for k^n times: for all spots of [0 ~ n - 1] each spot tries all k values [k-1 ~ 0]
51+
52+
This is more greedy: will generate one correct solution
53+
*/
54+
class Solution {
55+
public String crackSafe(int n, int k) {
56+
//if (n == 1) return "0";
57+
58+
Set<String> set = new HashSet<>();
59+
StringBuffer sb = new StringBuffer();
60+
for (int i = 0; i < n; i++) sb.append("0");
61+
set.add(sb.toString());
62+
63+
for (int i = 0; i < Math.pow(k, n); i++) {
64+
String tail = sb.substring(sb.length() - n + 1); // last n - 1 chars
65+
for (int j = k - 1; j >= 0; j--) {
66+
String newStr = tail + j;
67+
if (!set.contains(newStr)) {
68+
set.add(newStr);
69+
sb.append(j);
70+
break;
71+
}
72+
}
73+
}
74+
75+
return sb.toString();
76+
}
77+
}
78+
79+
80+
// DFS
81+
class Solution {
82+
public String crackSafe(int n, int k) {
83+
Set<String> visited = new HashSet<>();
84+
StringBuffer sb = new StringBuffer();
85+
for (int i = 0; i < n; i++) sb.append("0");
86+
visited.add(sb.toString());
87+
88+
// recursive, dfs
89+
dfs(n, k, Math.pow(k, n), visited, sb);
90+
return sb.toString();
91+
}
92+
93+
private void dfs(int n, int k, double total, Set<String> visited, StringBuffer sb) {
94+
if (visited.size() == total) return;
95+
String tail = sb.substring(sb.length() - n + 1);
96+
for (int j = k - 1; j >= 0; j--) {
97+
String newStr = tail + j;
98+
if (visited.contains(newStr)) continue;
99+
visited.add(newStr);
100+
sb.append(j);
101+
dfs(n, k, total, visited, sb);
102+
}
103+
}
104+
}
105+
```

Java/Graph Valid Tree.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
M
2-
1532583365
2+
1534225885
33
tags: DFS, BFS, Union Find, Graph
44

55
给一个数字n代表n nodes, marked from 1 ~ n, 和一串undirected edge int[][].
@@ -16,10 +16,12 @@
1616
- http://www.lintcode.com/en/problem/find-the-weak-connected-component-in-the-directed-graph/
1717

1818
#### DFS
19+
- Very similar to `Redundant Connection`
1920
- Create adjacent list graph: Map<Integer, List<Integer>>
2021
- 检查:
2122
- 1. 是否有cycle using dfs, check boolean[] visited
2223
- 2. 是否所有的node全部链接起来: validate if all edge connected: # of visited node should match graph size
24+
- IMPORTANT: use `pre` node to avoid linking backward/infinite loop such as (1)->(2), and (2)->(1)
2325

2426
#### BFS
2527
- (还没做, 可以写一写)
@@ -97,10 +99,9 @@ private int find(int x) {
9799
*/
98100
class Solution {
99101
public boolean validTree(int n, int[][] edges) {
100-
// No node, false
101102
if (n == 0) return false;
102103

103-
Map<Integer, List<Integer>> graph = buildGraph(n, edges);
104+
Map<Integer, Set<Integer>> graph = buildGraph(n, edges);
104105
Set<Integer> visited = new HashSet<>();
105106

106107
// dfs(graph, visited, i, -1) and validate cycle
@@ -111,10 +112,10 @@ public boolean validTree(int n, int[][] edges) {
111112
}
112113

113114
// build graph in form of adjacent list
114-
private Map<Integer, List<Integer>> buildGraph(int n, int[][] edges) {
115-
Map<Integer, List<Integer>> graph = new HashMap<>();
115+
private Map<Integer, Set<Integer>> buildGraph(int n, int[][] edges) {
116+
Map<Integer, Set<Integer>> graph = new HashMap<>();
116117
for (int i = 0; i < n; i++) {
117-
if (!graph.containsKey(i)) graph.put(i, new ArrayList<>());
118+
graph.putIfAbsent(i, new HashSet<>());
118119
}
119120
for (int[] edge: edges) {
120121
graph.get(edge[0]).add(edge[1]);
@@ -124,11 +125,12 @@ private Map<Integer, List<Integer>> buildGraph(int n, int[][] edges) {
124125
}
125126

126127
// dfs: mark visited nodes, and keep dfs into children nodes
127-
private boolean dfs(Map<Integer, List<Integer>> graph, Set<Integer> visited, int i, int pre) {
128-
if (visited.contains(i)) return false;
129-
visited.add(i);
130-
for (int child : graph.get(i)) {
131-
if (child != pre && !dfs(graph, visited, child, i)) return false;
128+
private boolean dfs(Map<Integer, Set<Integer>> graph, Set<Integer> visited, int curr, int pre) {
129+
if (visited.contains(curr)) return false;
130+
visited.add(curr);
131+
for (int child : graph.get(curr)) {
132+
if (child == pre) continue;
133+
if (!dfs(graph, visited, child, curr)) return false;
132134
}
133135
return true;
134136
}

Java/Isomorphic Strings.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
E
2+
1534215677
3+
tags: Hash Table
24

3-
HashMap 来确认match有几种情况考虑:
5+
#### HashMap
6+
- two failture cases:
7+
- same key, value not matching
8+
- two key maps to same value
49

10+
#### Previous note
511
1. Match. 就是map.containsKey, map.containsValue, and char1 == char2. Perfect.
6-
712
2. Either Key not exist, or Value not exit. False;
8-
913
3. Both key and Value exist, but map.get(char1) != char2. Miss-match. False.
10-
1114
4. None of Key or Value exist in HashMap. Then add the match.
1215

1316
```
@@ -34,6 +37,24 @@ Hide Similar Problems (E) Word Pattern
3437
3538
*/
3639

40+
class Solution {
41+
public boolean isIsomorphic(String s, String t) {
42+
if (s == null || t == null || s.length() != t.length()) return false;
43+
Map<Character, Character> map = new HashMap<>();
44+
45+
for (int i = 0; i < s.length(); i++) {
46+
char charS = s.charAt(i), charT = t.charAt(i);
47+
if (map.containsKey(charS)) {
48+
if (map.get(charS) != charT) return false; // same key, value not matching
49+
} else {
50+
if (map.containsValue(charT)) return false; // two key maps to same value
51+
map.put(charS, charT);
52+
}
53+
}
54+
55+
return true;
56+
}
57+
}
3758

3859
//Use hashMap<Char,Char> to store matches. If conflict, return false
3960
public class Solution {

Java/Redundant Connection II.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
H
2+
1534232150
3+
tags: Tree, DFS, Union Find, Graph
4+
5+
#### Union Find
6+
- 讨论3种情况
7+
- http://www.cnblogs.com/grandyang/p/8445733.html
8+
9+
```
10+
/*
11+
In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) for which all other nodes are descendants of this node, plus every node has exactly one parent, except for the root node which has no parents.
12+
13+
The given input is a directed graph that started as a rooted tree with N nodes (with distinct values 1, 2, ..., N), with one additional directed edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed.
14+
15+
The resulting graph is given as a 2D-array of edges. Each element of edges is a pair [u, v] that represents a directed edge connecting nodes u and v, where u is a parent of child v.
16+
17+
Return an edge that can be removed so that the resulting graph is a rooted tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array.
18+
19+
Example 1:
20+
Input: [[1,2], [1,3], [2,3]]
21+
Output: [2,3]
22+
Explanation: The given directed graph will be like this:
23+
1
24+
/ \
25+
v v
26+
2-->3
27+
Example 2:
28+
Input: [[1,2], [2,3], [3,4], [4,1], [1,5]]
29+
Output: [4,1]
30+
Explanation: The given directed graph will be like this:
31+
5 <- 1 -> 2
32+
^ |
33+
| v
34+
4 <- 3
35+
Note:
36+
The size of the input 2D-array will be between 3 and 1000.
37+
Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array.
38+
*/
39+
40+
/*
41+
- find inDegree == 2
42+
- union and return cycle item
43+
- if cycle not exist, return the inDegree==2 edge
44+
45+
*/
46+
class Solution {
47+
int[] parent;
48+
public int[] findRedundantDirectedConnection(int[][] edges) {
49+
int n = edges.length;
50+
parent = new int[n + 1];
51+
52+
// find the edges where inDegree == 2
53+
int[] first = null, second = null;
54+
for (int[] edge : edges) {
55+
int x = edge[0], y = edge[1];
56+
if (parent[y] == 0) {
57+
parent[y] = x;
58+
} else {
59+
first = new int[]{parent[y], y};
60+
second = new int[]{edge[0], edge[1]};
61+
edge[1] = 0; // why?
62+
}
63+
}
64+
// re-init unionFind
65+
for (int i = 0; i <= n; i++) parent[i] = i;
66+
67+
// Union
68+
for (int[] edge : edges) {
69+
int x = edge[0], y = edge[1];
70+
if (y == 0) continue;
71+
int parentX = find(x), parentY = find(y);
72+
if (parentX == parentY) return first == null ? edge : first;
73+
parent[parentX] = parentY;
74+
}
75+
76+
return second;
77+
}
78+
79+
public int find(int x) {
80+
int parentX = parent[x];
81+
if (parentX == x) return parentX;
82+
return parent[x] = find(parentX);
83+
}
84+
}
85+
```

0 commit comments

Comments
 (0)