Skip to content

Commit fd1510c

Browse files
committed
Merge branch 'piotrkruk-master'
2 parents 7aa69e1 + 19498e1 commit fd1510c

File tree

6 files changed

+160
-36
lines changed

6 files changed

+160
-36
lines changed

README.md

+26-26
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,21 @@ This is a collection of algorithms and data structures which I've implement over
4444
* [Hash Array Mapped Trie (HAMT)](src/com/jwetherell/algorithms/data_structures/HashArrayMappedTrie.java)
4545
* [Hash Map (associative array)](src/com/jwetherell/algorithms/data_structures/HashMap.java)
4646
* [Interval Tree](src/com/jwetherell/algorithms/data_structures/IntervalTree.java)
47-
* [Implicit Key Treap]((src/com/jwetherell/algorithms/data_structures/ImplicitKeyTreap.java))
47+
* [Implicit Key Treap](src/com/jwetherell/algorithms/data_structures/ImplicitKeyTreap.java)
4848
* [KD Tree (k-dimensional tree or k-d tree)](src/com/jwetherell/algorithms/data_structures/KDTree.java)
49-
* [List [backed by an array or a linked list]]((src/com/jwetherell/algorithms/data_structures/List.java))
49+
* [List [backed by an array or a linked list]](src/com/jwetherell/algorithms/data_structures/List.java)
5050
* [Matrix](src/com/jwetherell/algorithms/data_structures/Matrix.java)
5151
* [Patricia Trie](src/com/jwetherell/algorithms/data_structures/PatriciaTrie.java)
5252
* [Quad-Tree (Point-Region or MX-CIF)](src/com/jwetherell/algorithms/data_structures/QuadTree.java)
5353
* [Queue [backed by an array or a linked list]](src/com/jwetherell/algorithms/data_structures/Queue.java)
54-
* [Radix Trie (associative array) [backed by a Patricia Trie]](src/com/jwetherell/algorithms/data_structures/RadixTree.java)
54+
* [Radix Trie (associative array) [backed by a Patricia Trie]](src/com/jwetherell/algorithms/data_structures/RadixTrie.java)
5555
* [Red-Black Tree](src/com/jwetherell/algorithms/data_structures/RedBlackTree.java)
5656
* [Segment Tree](src/com/jwetherell/algorithms/data_structures/SegmentTree.java)
5757
* [Skip List](src/com/jwetherell/algorithms/data_structures/SkipList.java)
5858
* [Splay Tree](src/com/jwetherell/algorithms/data_structures/SplayTree.java)
5959
* [Stack [backed by an array or a linked list]](src/com/jwetherell/algorithms/data_structures/Stack.java)
6060
* [Suffix Tree (Ukkonen's algorithm)](src/com/jwetherell/algorithms/data_structures/SuffixTree.java)
61-
* [Suffix Trie [backed by a Trie]](src/com/jwetherell/algorithms/data_structures/SufficTrie.java)
61+
* [Suffix Trie [backed by a Trie]](src/com/jwetherell/algorithms/data_structures/SuffixTrie.java)
6262
* [Treap](src/com/jwetherell/algorithms/data_structures/Treap.java)
6363
* [Tree Map (associative array) [backed by an AVL Tree]](src/com/jwetherell/algorithms/data_structures/TreeMap.java)
6464
* [Trie](src/com/jwetherell/algorithms/data_structures/Trie.java)
@@ -149,39 +149,39 @@ This is a collection of algorithms and data structures which I've implement over
149149

150150
## Search
151151
* Get index of value in array
152-
+ [Linear](src/com/jwetherell/algorithms/Sequences/LinearSearch.java)
153-
+ [Quickselect](src/com/jwetherell/algorithms/Sequences/QuickSelect.java)
154-
+ [Binary [sorted array input only]](src/com/jwetherell/algorithms/Sequences/BinarySearch.java)
155-
+ [Lower bound [sorted array input only]](src/com/jwetherell/algorithms/Sequences/LpperBound.java)
156-
+ [Upper bound [sorted array input only]](src/com/jwetherell/algorithms/Sequences/UpperBound.java)
152+
+ [Linear](src/com/jwetherell/algorithms/search/LinearSearch.java)
153+
+ [Quickselect](src/com/jwetherell/algorithms/search/QuickSelect.java)
154+
+ [Binary [sorted array input only]](src/com/jwetherell/algorithms/search/BinarySearch.java)
155+
+ [Lower bound [sorted array input only]](src/com/jwetherell/algorithms/search/LowerBound.java)
156+
+ [Upper bound [sorted array input only]](src/com/jwetherell/algorithms/search/UpperBound.java)
157157
+ Optimized binary (binary until a threashold then linear) [sorted array input only]
158-
+ [Interpolation [sorted array input only]](src/com/jwetherell/algorithms/Sequences/InterpolationSearch.java)
158+
+ [Interpolation [sorted array input only]](src/com/jwetherell/algorithms/search/InterpolationSearch.java)
159159

160160
## Sequences
161-
* [Find longest common subsequence (dynamic programming)](src/com/jwetherell/algorithms/Sequences/LongestCommonSubsequence.java)
162-
* [Find longest increasing subsequence (dynamic programming)](src/com/jwetherell/algorithms/Sequences/LongestIncreasingSubsequence.java)
163-
* [Find number of times a subsequence occurs in a sequence (dynamic programming)](src/com/jwetherell/algorithms/Sequences/SubsequenceCounter.java)
164-
* [Find i-th element in a Fibonacci sequence](src/com/jwetherell/algorithms/Sequences/FibonacciSequence.java)
161+
* [Find longest common subsequence (dynamic programming)](src/com/jwetherell/algorithms/sequence/LongestCommonSubsequence.java)
162+
* [Find longest increasing subsequence (dynamic programming)](src/com/jwetherell/algorithms/sequence/LongestIncreasingSubsequence.java)
163+
* [Find number of times a subsequence occurs in a sequence (dynamic programming)](src/com/jwetherell/algorithms/sequence/SubsequenceCounter.java)
164+
* [Find i-th element in a Fibonacci sequence](src/com/jwetherell/algorithms/sequence/FibonacciSequence.java)
165165
+ using a loop
166166
+ using recursion
167167
+ using matrix multiplication
168168
+ using Binet's formula
169-
* [Find total of all elements in a sequence(Arithmetic Progression)](src/com/jwetherell/algorithms/Sequences/ArithmeticProgression.java)
169+
* [Find total of all elements in a sequence(Arithmetic Progression)](src/com/jwetherell/algorithms/sequence/ArithmeticProgression.java)
170170
+ using a loop
171171
+ using Triangular numbers
172-
* [Largest sum of contiguous subarray (Kadane's algorithm)](src/com/jwetherell/algorithms/Sequences/LargestSumContiguousSubarray.java)
173-
* [Longest palin­dromic sub­se­quence (dynamic programming)](src/com/jwetherell/algorithms/Sequences/LongestPalin­dromicSub­se­quence.java)
172+
* [Largest sum of contiguous subarray (Kadane's algorithm)](src/com/jwetherell/algorithms/sequence/LargestSumContiguousSubarray.java)
173+
* [Longest palin­dromic sub­se­quence (dynamic programming)](src/com/jwetherell/algorithms/sequence/LongestPalindromicSubsequence.java)
174174

175175
## Sorts
176-
* [American Flag Sort](src/com/jwetherell/algorithms/Sorts/AmericanFlagSort.java)
177-
* [Bubble Sort](src/com/jwetherell/algorithms/Sorts/BubbleSort.java)
178-
* [Counting Sort (Integers only)](src/com/jwetherell/algorithms/Sorts/CountingSort.java)
179-
* [Heap Sort](src/com/jwetherell/algorithms/Sorts/HeapSort.java)
180-
* [Insertion Sort](src/com/jwetherell/algorithms/Sorts/InsertionSort.java)
181-
* [Merge Sort](src/com/jwetherell/algorithms/Sorts/AMergeSort.java)
182-
* [Quick Sort](src/com/jwetherell/algorithms/Sorts/QuickSort.java)
183-
* [Radix Sort (Integers only)](src/com/jwetherell/algorithms/Sorts/RadixSort.java)
184-
* [Shell's Sort](src/com/jwetherell/algorithms/Sorts/ShellSort.java)
176+
* [American Flag Sort](src/com/jwetherell/algorithms/sorts/AmericanFlagSort.java)
177+
* [Bubble Sort](src/com/jwetherell/algorithms/sorts/BubbleSort.java)
178+
* [Counting Sort (Integers only)](src/com/jwetherell/algorithms/sorts/CountingSort.java)
179+
* [Heap Sort](src/com/jwetherell/algorithms/sorts/HeapSort.java)
180+
* [Insertion Sort](src/com/jwetherell/algorithms/sorts/InsertionSort.java)
181+
* [Merge Sort](src/com/jwetherell/algorithms/sorts/MergeSort.java)
182+
* [Quick Sort](src/com/jwetherell/algorithms/sorts/QuickSort.java)
183+
* [Radix Sort (Integers only)](src/com/jwetherell/algorithms/sorts/RadixSort.java)
184+
* [Shell's Sort](src/com/jwetherell/algorithms/sorts/ShellSort.java)
185185

186186
## String Functions
187187
### [String Functions](src/com/jwetherell/algorithms/strings/StringFunctions.java)

src/com/jwetherell/algorithms/data_structures/DisjointSet.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public boolean equals(Object o) {
120120
final Item<T> i = (Item<T>) o;
121121
if ((i.parent!=null && parent!=null) && !(i.parent.value.equals(parent.value)))
122122
return false;
123-
if ((i.value!=null && value!=null) && !(value.equals(value)))
123+
if ((i.value!=null && value!=null) && !(i.value.equals(value)))
124124
return false;
125125
return true;
126126
}

src/com/jwetherell/algorithms/data_structures/HashMap.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ public V remove(K key) {
514514
@Override
515515
public void clear() {
516516
for (int i=0; i<array.length; i++)
517-
array = null;
517+
array[i] = null;
518518
size = 0;
519519
}
520520

@@ -597,9 +597,9 @@ private int getNextIndex(int input) {
597597
* @return Integer which represents the key.
598598
*/
599599
private int indexOf(K key) {
600-
int k = key.hashCode() % hashingKey;
601-
if (k>=array.length)
602-
k = k - ((k/array.length) * array.length);
600+
int k = Math.abs(key.hashCode()) % hashingKey;
601+
if (k >= array.length)
602+
k = k - ((k / array.length) * array.length);
603603
return k;
604604
}
605605

src/com/jwetherell/algorithms/graph/DepthFirstTraversal.java

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
1+
package com.jwetherell.algorithms.graph;
2+
13
import java.util.Stack;
24

3-
//implemented Depth First Travesal in given "Directed graph" (Adjacany matrix)
5+
/**
6+
* Implemented Depth First Traversal in given the "Directed graph" (Adjacency matrix)
7+
*
8+
* @author Justin Wetherell <phishman3579@gmail.com>
9+
*
10+
*/
411
class DepthFirstTraversal {
512

613
public static int[] arr;
714
public static int k = 0;
815

916
public static void depthFirstTraversal(int[][] a, int[] visited,int source){
10-
for (int i = 0; i < visited.length; i++) {
17+
for (int i = 0; i < visited.length; i++)
1118
visited[i] = -1;
12-
}
13-
Stack<Integer>stack = new Stack();
19+
20+
final Stack<Integer> stack = new Stack<Integer>();
1421
int element = source;
1522
int i = source;
1623
int n = visited.length - 1;
@@ -38,4 +45,3 @@ public static void depthFirstTraversal(int[][] a, int[] visited,int source){
3845
}
3946
}
4047
}
41-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.jwetherell.algorithms.strings;
2+
3+
/**
4+
* The longest palindromic substring or longest symmetric factor problem
5+
* is the problem of finding a maximum-length contiguous substring of a given string that is also a palindrome.
6+
* <p>
7+
* The longest palindromic substring problem should not be confused with
8+
* the different problem of finding the longest palindromic subsequence.
9+
* <br>
10+
* Manacher's algorithm finds the longest palindromic substring in linear time O(n); where n = length(input)
11+
* <br>
12+
* https://en.wikipedia.org/wiki/Longest_palindromic_substring#Manacher.27s_algorithm
13+
* <br>
14+
* @author Piotr Kruk <pka.kruk@gmail.com>
15+
* @author Justin Wetherell <phishman3579@gmail.com>
16+
*/
17+
public class Manacher {
18+
19+
private Manacher() {}
20+
21+
/**
22+
* This function implements Manacher's algorithm that finds
23+
* the longest palindromic substring in a linear time
24+
* If there is no unique longest palindromic substring it returns the first one to occur
25+
*
26+
* @param input
27+
* @return the longest palindromic substring in input
28+
*/
29+
public static String getLongestPalindromicSubstring(String input) {
30+
if (input == null)
31+
return null;
32+
33+
final int length = input.length();
34+
if (length == 0)
35+
return "";
36+
37+
// arr represents input string in a way that will act the same for strings of even and uneven length
38+
// i.e. '#' is placed between each letter from input
39+
final char[] arr = new char[2 * length + 1];
40+
for (int i = length - 1; i >= 0; i--) {
41+
arr[2 * i + 1] = input.charAt(i);
42+
arr[2 * i] = '#';
43+
}
44+
arr[2 * length] = '#';
45+
46+
final int arrLength = length * 2;
47+
48+
// LPS[i] - palindrome span(radius) with center at arr[i]
49+
final int[] LPS = new int[arrLength + 1];
50+
int p = 0;
51+
for (int i = 1; i <= arrLength; i++) {
52+
LPS[i] = 0;
53+
if (LPS[p] + p >= i)
54+
LPS[i] = Math.min(LPS[2 * p - i], p + LPS[p] - i);
55+
while (i + LPS[i] + 1 <= arrLength && i - LPS[i] - 1 >= 0 && arr[i + LPS[i] + 1] == arr[i - LPS[i] - 1])
56+
LPS[i]++;
57+
if (p + LPS[p] < i + LPS[i])
58+
p = i;
59+
}
60+
61+
// find the palindrome with the biggest span
62+
int valueMax = 0;
63+
int indexMax = 0;
64+
for (int i = 0; i < arrLength; i++) {
65+
if (valueMax < LPS[i]) {
66+
valueMax = LPS[i];
67+
indexMax = i;
68+
}
69+
}
70+
71+
// reconstruct the palindrome given its index in LPS and span
72+
final int palindromeSpan = valueMax / 2;
73+
if (indexMax % 2 == 0) {
74+
return input.substring(indexMax/2 - palindromeSpan, indexMax/2 + palindromeSpan);
75+
} else {
76+
return input.substring(indexMax/2 - palindromeSpan, indexMax/2 + palindromeSpan + 1);
77+
}
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.jwetherell.algorithms.strings.test;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import java.util.List;
5+
import java.util.Arrays;
6+
import com.jwetherell.algorithms.strings.Manacher;
7+
import org.junit.Test;
8+
9+
public class ManacherTests {
10+
11+
@Test
12+
public void testGetLongestPalindromicSubstring() throws Exception {
13+
final List<Object[]> data = Arrays.asList(
14+
new Object[][]{
15+
{null, null},
16+
{"", ""},
17+
{"a", "a"},
18+
{"aa", "aa"},
19+
{"aaa", "aaa"},
20+
{"abaa", "aba"},
21+
{"abba", "abba"},
22+
{"abbaaa", "abba"},
23+
{"abbabb", "bbabb"},
24+
{"bananas", "anana"},
25+
{"bakskskba", "ksksk"},
26+
{"itisneveroddoreven", "neveroddoreven"},
27+
{"ABCDEFGHIJKLMNOPQRSTUVWXYZ", "A"},
28+
{"I like bananas", "anana"}
29+
30+
}
31+
);
32+
for (Object[] testCase: data) {
33+
String input = (String) testCase[0];
34+
String expected = (String) testCase[1];
35+
String result = Manacher.getLongestPalindromicSubstring(input);
36+
assertEquals(expected, result);
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)