Skip to content

Commit d34d303

Browse files
committed
Update
1 parent a301c61 commit d34d303

File tree

5 files changed

+218
-1
lines changed

5 files changed

+218
-1
lines changed

src/graph/AlienDictionary.java

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package graph;
2+
3+
import java.util.*;
4+
5+
/**
6+
* Description: https://leetcode.com/problems/alien-dictionary
7+
* Difficulty: Hard
8+
* Time complexity: O(n)
9+
* Space complexity: O(n)
10+
*/
11+
public class AlienDictionary {
12+
13+
public String alienOrderViaTopologicalSort(String[] words) {
14+
Map<Character, List<Character>> adjList = buildAdjList(words);
15+
if (adjList.isEmpty()) return "";
16+
17+
// topologically sorted (DESC) graph nodes
18+
StringBuilder sortedChars = new StringBuilder();
19+
int[] visited = new int[26];
20+
for (char c : adjList.keySet()) {
21+
if (visited[c - 'a'] == 0 && hasCycle(c, adjList, visited, sortedChars)) {
22+
// cycle found -> no valid answer
23+
return "";
24+
}
25+
}
26+
27+
return sortedChars.reverse().toString();
28+
}
29+
30+
private boolean hasCycle(
31+
char start,
32+
Map<Character, List<Character>> adjList,
33+
int[] visited,
34+
StringBuilder sortedChars) {
35+
Deque<Character> stack = new LinkedList<>();
36+
stack.push(start);
37+
38+
while (!stack.isEmpty()) {
39+
char current = stack.pop();
40+
if (visited[current - 'a'] == 0) {
41+
visited[current - 'a'] = 1;
42+
stack.push(current);
43+
44+
for (char neighbor : adjList.getOrDefault(current, List.of())) {
45+
if (visited[neighbor - 'a'] == 1) return true;
46+
if (visited[neighbor - 'a'] == 0) {
47+
stack.push(neighbor);
48+
}
49+
}
50+
} else if (visited[current - 'a'] == 1) {
51+
visited[current - 'a'] = 2;
52+
sortedChars.append(current);
53+
}
54+
}
55+
56+
return false;
57+
}
58+
59+
private Map<Character, List<Character>> buildAdjList(String[] words) {
60+
Map<Character, List<Character>> adjList = new HashMap<>();
61+
62+
// find all nodes
63+
for (String word : words) {
64+
for (char c : word.toCharArray()) {
65+
adjList.putIfAbsent(c, new ArrayList<>());
66+
}
67+
}
68+
69+
// find all edges
70+
for (int i = 1; i < words.length; i++) {
71+
String word1 = words[i - 1];
72+
String word2 = words[i];
73+
74+
// prefix goes after longer word -> invalid sequence
75+
if (word2.length() < word1.length() && word1.startsWith(word2)) return Map.of();
76+
77+
for (int j = 0; j < Math.min(word1.length(), word2.length()); j++) {
78+
// find first non match
79+
if (word1.charAt(j) != word2.charAt(j)) {
80+
adjList.get(word1.charAt(j)).add(word2.charAt(j));
81+
break;
82+
}
83+
}
84+
}
85+
86+
return adjList;
87+
}
88+
}

src/graph/CourseSchedule2.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class CourseSchedule2 {
1212
private int[] visited;
1313
private Deque<Integer> topologicalPath;
1414

15-
public int[] findOrder(int numCourses, int[][] prerequisites) {
15+
public int[] findOrderViaTopologicalSort(int numCourses, int[][] prerequisites) {
1616
visited = new int[numCourses];
1717
topologicalPath = new LinkedList<>();
1818
Map<Integer, List<Integer>> adjList = buildAdjList(prerequisites);

src/linked_list/PartitionList.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package linked_list;
2+
3+
/**
4+
* Description: https://leetcode.com/problems/partition-list
5+
* Difficulty: Medium
6+
* Time complexity: O(n)
7+
* Space complexity: O(1)
8+
*/
9+
public class PartitionList {
10+
11+
public ListNode partition(ListNode head, int x) {
12+
ListNode dummyLeft = new ListNode();
13+
ListNode left = dummyLeft;
14+
ListNode dummyRight = new ListNode();
15+
ListNode right = dummyRight;
16+
17+
while (head != null) {
18+
if (head.val < x) {
19+
left.next = head;
20+
left = left.next;
21+
} else {
22+
right.next = head;
23+
right = right.next;
24+
}
25+
26+
head = head.next;
27+
}
28+
29+
right.next = null;
30+
left.next = dummyRight.next;
31+
return dummyLeft.next;
32+
}
33+
34+
private static class ListNode {
35+
int val;
36+
ListNode next;
37+
}
38+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package math;
2+
3+
/**
4+
* Description: https://leetcode.com/problems/check-if-it-is-a-straight-line
5+
* Difficulty: Easy
6+
* Time complexity: O(n)
7+
* Space complexity: O(1)
8+
*/
9+
public class CheckIfItIsStraightLine {
10+
11+
public boolean checkStraightLine(int[][] coordinates) {
12+
double slope = getSlope(coordinates[0], coordinates[1]);
13+
for (int i = 2; i < coordinates.length; i++) {
14+
if (getSlope(coordinates[i], coordinates[i - 1]) != slope) return false;
15+
}
16+
17+
return true;
18+
}
19+
20+
private double getSlope(int[] point1, int[] point2) {
21+
if (point1[0] == point2[0]) return Double.POSITIVE_INFINITY;
22+
if (point1[1] == point2[1]) return 0.0;
23+
24+
return (double) (point1[1] - point2[1]) / (point1[0] - point2[0]);
25+
}
26+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package trie;
2+
3+
import java.util.*;
4+
5+
/**
6+
* Description: https://leetcode.com/problems/search-suggestions-system
7+
* Difficulty: Medium
8+
*/
9+
public class SearchSuggestionsSystem {
10+
11+
private static final int SUGGESTIONS_SIZE_LIMIT = 3;
12+
13+
public List<List<String>> suggestedProducts(String[] products, String searchWord) {
14+
Node trie = buildTrie(products);
15+
16+
List<List<String>> suggestions = new ArrayList<>();
17+
boolean noMoreSuggestions = false;
18+
for (char c : searchWord.toCharArray()) {
19+
Node child = trie.children.get(c);
20+
if (child == null) noMoreSuggestions = true;
21+
22+
if (noMoreSuggestions) {
23+
suggestions.add(List.of());
24+
} else {
25+
suggestions.add(child.suggestions);
26+
trie = child;
27+
}
28+
}
29+
30+
return suggestions;
31+
}
32+
33+
private Node buildTrie(String[] products) {
34+
Arrays.sort(products);
35+
36+
Node root = new Node();
37+
for (String product : products) {
38+
Node current = root;
39+
for (char c : product.toCharArray()) {
40+
Node child = current.children.computeIfAbsent(c, __ -> new Node());
41+
child.addSuggestion(product);
42+
current = child;
43+
}
44+
}
45+
46+
return root;
47+
}
48+
49+
private static class Node {
50+
51+
private final Map<Character, Node> children;
52+
private final List<String> suggestions;
53+
54+
public Node() {
55+
this.children = new HashMap<>();
56+
this.suggestions = new ArrayList<>();
57+
}
58+
59+
public void addSuggestion(String product) {
60+
if (suggestions.size() < SUGGESTIONS_SIZE_LIMIT) {
61+
suggestions.add(product);
62+
}
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)