Skip to content

Commit ce291ee

Browse files
committed
Added solution for multisearch with bruteforce and trie
1 parent 21ea598 commit ce291ee

File tree

5 files changed

+438
-0
lines changed

5 files changed

+438
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package com.eprogrammerz.examples.algorithm.crackingCoding;
2+
3+
import org.junit.Test;
4+
5+
import java.util.*;
6+
7+
import static org.junit.Assert.assertEquals;
8+
9+
/**
10+
* Given a list of words, write a program to find the longest word made of other words in the list.
11+
*/
12+
public class LongestWord {
13+
String findLongestWord(String[] words) {
14+
Arrays.sort(words, (s1, s2) -> s2.length() - s1.length());
15+
16+
Set<String> wordExists = new HashSet<>(Arrays.asList(words));
17+
18+
for (String word : words) {
19+
if (isValid(wordExists, word, 1, false)) {
20+
return word;
21+
}
22+
}
23+
return "";
24+
}
25+
26+
private boolean isValid(Set<String> wordExists, String word, int idx, boolean isPart) {
27+
if (isPart && wordExists.contains(word)) return true;
28+
if (word.length() <= idx) return false;
29+
30+
String left = word.substring(0, idx);
31+
String right = word.substring(idx);
32+
33+
if (wordExists.contains(left) && isValid(wordExists, right, 1, true)) {
34+
return true;
35+
} else {
36+
return isValid(wordExists, word, idx + 1, false);
37+
}
38+
}
39+
40+
@Test
41+
public void testFindLongestWord() {
42+
String[] arr = "cat, banana, dog, nana, walk, walker, dogwalker, dogwalkercate, dogwalkercat".split(", ");
43+
String actual = findLongestWord(arr);
44+
assertEquals("dogwalkercat", actual);
45+
}
46+
47+
48+
/**
49+
* This one is better version since it is more readable
50+
*
51+
* @param words
52+
* @return
53+
*/
54+
String longestWord(String[] words) {
55+
Arrays.sort(words, (w1, w2) -> w2.length() - w1.length());
56+
57+
Map<String, Boolean> map = new HashMap<>();
58+
59+
for (String word : words) {
60+
map.put(word, true);
61+
}
62+
63+
for (String word : words) {
64+
if (canBuild(word, true, map)) {
65+
return word;
66+
}
67+
}
68+
return "";
69+
}
70+
71+
private boolean canBuild(String word, boolean isOriginalWord, Map<String, Boolean> map) {
72+
if (!isOriginalWord && map.containsKey(word)) return map.get(word);
73+
74+
for (int i = 1; i < word.length(); i++) {
75+
String left = word.substring(0, i);
76+
String right = word.substring(i);
77+
78+
if (map.containsKey(left) && map.get(left) && canBuild(right, false, map)) {
79+
return true;
80+
}
81+
}
82+
83+
map.put(word, false);
84+
85+
return false;
86+
}
87+
88+
@Test
89+
public void testLongestWord() {
90+
String[] arr = "cat, banana, dog, nana, walk, walker, dogwalker, dogwalkercate, dogwalkercat".split(", ");
91+
String actual = longestWord(arr);
92+
assertEquals("dogwalkercat", actual);
93+
}
94+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.eprogrammerz.examples.algorithm.crackingCoding;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.assertEquals;
6+
7+
public class MasseuseScheduling {
8+
int findMaxBookTime(int[] schedules) {
9+
int[] mem = new int[schedules.length];
10+
return findMaxBookTime(schedules, 0, mem);
11+
}
12+
13+
private int findMaxBookTime(int[] schedules, int idx, int[] mem) {
14+
if (schedules.length <= idx) return 0;
15+
16+
if (mem[idx] == 0) {
17+
int withThisReservation = schedules[idx] + findMaxBookTime(schedules, idx + 2, mem);
18+
19+
int withoutThisReservation = findMaxBookTime(schedules, idx + 1, mem);
20+
mem[idx] = Math.max(withThisReservation, withoutThisReservation);
21+
}
22+
return mem[idx];
23+
}
24+
25+
@Test
26+
public void testFindMaxBookTime() {
27+
int[] input = new int[]{30, 15, 60, 75, 45, 15, 15, 45};
28+
assertEquals(180, findMaxBookTime(input));
29+
}
30+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.eprogrammerz.examples.algorithm.crackingCoding;
2+
3+
import org.junit.Test;
4+
5+
import java.util.*;
6+
7+
import static org.junit.Assert.assertEquals;
8+
9+
/**
10+
* Given a string band an array of smaller strings T, design a method to search b for each small string in T.
11+
* return oneAway;
12+
* <p>
13+
* Let's start with an example:
14+
* T = {"is", "ppi", "hi", "sis", "i", "ssippi"}
15+
* b = "mississippi"
16+
*/
17+
public class MultiSearch {
18+
/**
19+
* O(n * k * t)
20+
* where n = number of elements in array
21+
* k = size of big string
22+
* t = size of small string
23+
*
24+
* @param smalls
25+
* @param big
26+
* @return
27+
*/
28+
Map<String, List<Integer>> searchAll(String[] smalls, String big) {
29+
// go over each of small
30+
// find locations for them in big
31+
// add to result map
32+
Map<String, List<Integer>> map = new HashMap<>();
33+
34+
for (String small : smalls) { // O(n * k * t)
35+
List<Integer> locations = lookupString(big, small);
36+
map.put(small, locations);
37+
}
38+
return map;
39+
}
40+
41+
private List<Integer> lookupString(String big, String small) {
42+
List<Integer> locations = new ArrayList<>();
43+
for (int i = 0; i < (big.length() - small.length() + 1); i++) { // O(k * t)
44+
if (big.charAt(i) == small.charAt(0) && matches(big, i, small)) {
45+
// there is possibility, to look for all string and if it matches, then add i to locations
46+
locations.add(i);
47+
}
48+
}
49+
return locations;
50+
}
51+
52+
private boolean matches(String big, int start, String small) {
53+
for (int i = 0; i < small.length(); i++) { // O(t)
54+
if (small.charAt(i) != big.charAt(start++)) {
55+
return false;
56+
}
57+
}
58+
return true;
59+
}
60+
61+
@Test
62+
public void testSearchAll() {
63+
String[] arr = new String[]{"is", "ppi", "hi", "sis", "i", "ssippi"};
64+
Map<String, List<Integer>> locations = searchAll(arr, "mississippi"); // {hi=[], ssippi=[5], ppi=[8], i=[1, 4, 7, 10], is=[1, 4], sis=[3]}
65+
assertEquals(Arrays.asList(1, 4, 7, 10), locations.get("i"));
66+
assertEquals(Arrays.asList(8), locations.get("ppi"));
67+
}
68+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package com.eprogrammerz.examples.algorithm.crackingCoding;
2+
3+
import org.junit.Test;
4+
5+
import java.util.*;
6+
import java.util.stream.Collectors;
7+
8+
import static org.junit.Assert.assertEquals;
9+
10+
public class MultiSearchTrie {
11+
Map<String, List<Integer>> searchAll(String[] smalls, String big) {
12+
Map<String, List<Integer>> map = new HashMap<>();
13+
14+
Trie trie = createTrieFromString(big);
15+
16+
for (String small : smalls) {
17+
List<Integer> locations = trie.search(small);
18+
19+
// adjust the locations
20+
List<Integer> adjustedLocations = adjustLocations(locations, small.length());
21+
22+
map.put(small, adjustedLocations);
23+
}
24+
return map;
25+
}
26+
27+
private List<Integer> adjustLocations(List<Integer> locations, int delta) {
28+
if (locations == null) return Collections.emptyList();
29+
30+
return locations.stream().map(l -> l - delta).collect(Collectors.toList());
31+
}
32+
33+
private Trie createTrieFromString(String str) {
34+
Trie trie = new Trie();
35+
// populate trie
36+
for (int i = 0; i < str.length(); i++) {
37+
String remaining = str.substring(i);
38+
trie.insertString(remaining, i);
39+
}
40+
41+
return trie;
42+
}
43+
44+
class Trie {
45+
private TrieNode root = new TrieNode();
46+
47+
public Trie() {
48+
}
49+
50+
public Trie(String s) {
51+
this.root.insertString(s, 0);
52+
}
53+
54+
public List<Integer> search(String s) {
55+
return this.root.search(s);
56+
}
57+
58+
public void insertString(String str, int location) {
59+
this.root.insertString(str, location);
60+
}
61+
62+
public TrieNode getRoot() {
63+
return root;
64+
}
65+
}
66+
67+
private class TrieNode {
68+
char data;
69+
Map<Character, TrieNode> children;
70+
List<Integer> indices;
71+
72+
TrieNode() {
73+
children = new HashMap<>();
74+
indices = new ArrayList<>();
75+
}
76+
77+
void insertString(String s, int index) {
78+
indices.add(index);
79+
80+
if (s != null && s.length() > 0) {
81+
this.data = s.charAt(0);
82+
TrieNode child = null;
83+
84+
if (children.containsKey(data)) {
85+
child = children.get(data);
86+
} else {
87+
child = new TrieNode();
88+
children.put(data, child);
89+
}
90+
String remainder = s.substring(1);
91+
child.insertString(remainder, index + 1);
92+
} else {
93+
children.put('\0', null); // terminate
94+
}
95+
}
96+
97+
List<Integer> search(String s) {
98+
if (s == null || s.length() == 0) {
99+
return indices;
100+
} else {
101+
char first = s.charAt(0);
102+
if (children.containsKey(first)) {
103+
String remainder = s.substring(1);
104+
return children.get(first).search(remainder);
105+
}
106+
}
107+
return null;
108+
}
109+
110+
boolean terminates() {
111+
return children.containsKey('\0');
112+
}
113+
114+
TrieNode getChild(char c) {
115+
return children.get(c);
116+
}
117+
}
118+
119+
@Test
120+
public void testSearchAll() {
121+
String[] arr = new String[]{"is", "ppi", "hi", "sis", "i", "ssippi"};
122+
Map<String, List<Integer>> locations = searchAll(arr, "mississippi"); // {hi=[], ssippi=[5], ppi=[8], i=[1, 4, 7, 10], is=[1, 4], sis=[3]}
123+
assertEquals(Arrays.asList(1, 4, 7, 10), locations.get("i"));
124+
assertEquals(Arrays.asList(8), locations.get("ppi"));
125+
}
126+
}

0 commit comments

Comments
 (0)