├── .gitignore
├── .idea
├── .name
├── encodings.xml
├── misc.xml
├── modules.xml
├── scopes
│ └── scope_settings.xml
├── syringe.iml
├── vcs.xml
└── workspace.xml
├── DISCLAIMER
├── LICENSE
├── README.md
├── java
├── .classpath
├── .project
├── .settings
│ ├── org.eclipse.jdt.core.prefs
│ └── org.eclipse.jdt.ui.prefs
├── lib
│ └── junit-4.11.jar
├── src
│ ├── arrays
│ │ ├── Answer0toKRangeQuery.java
│ │ ├── BoundedQueue.java
│ │ ├── CountInversions.java
│ │ ├── FindCommonElements.java
│ │ ├── FindNumHops.java
│ │ ├── RearrangeInputToTarget.java
│ │ ├── SearchBitonicArray.java
│ │ └── SimplePhoneNumberAllotter.java
│ ├── binarytrees
│ │ ├── BstClosestNode.java
│ │ ├── BstCountTrees.java
│ │ ├── BstDoubleTree.java
│ │ ├── BstFindMode.java
│ │ ├── BstInsert.java
│ │ ├── BstIsBst.java
│ │ ├── BstLookup.java
│ │ ├── BstMinValue.java
│ │ ├── TreeConvertToSinglyLinkedList.java
│ │ ├── TreeDepth.java
│ │ ├── TreeHasPathSum.java
│ │ ├── TreeMirror.java
│ │ ├── TreeNode.java
│ │ ├── TreeNonRecursiveTraversals.java
│ │ ├── TreePrintPaths.java
│ │ ├── TreeReconstruct.java
│ │ ├── TreeRecursiveTraversals.java
│ │ ├── TreeSameTree.java
│ │ └── TreeSize.java
│ ├── bitsandbytes
│ │ └── NumSetBits.java
│ ├── cache
│ │ ├── Cache.java
│ │ └── LRUCache.java
│ ├── collections
│ │ ├── DeepIterator.java
│ │ ├── FilteringIterator.java
│ │ ├── HoppingIterator.java
│ │ ├── InorderIterator.java
│ │ ├── LevelOrderIterator.java
│ │ ├── MaxIterator.java
│ │ ├── MultiIterator.java
│ │ ├── PeekIterator.java
│ │ ├── PreorderIterator.java
│ │ └── RotatingIterator.java
│ ├── common
│ │ ├── ArrayUtils.java
│ │ ├── BitUtils.java
│ │ ├── ListUtils.java
│ │ ├── NumberUtils.java
│ │ └── Pair.java
│ ├── concurrency
│ │ ├── BoundedBlockingQueue.java
│ │ ├── FirstReadWriteLock.java
│ │ ├── ReadWriteLock.java
│ │ ├── SchedulingExecutor.java
│ │ ├── SecondReadWriteLock.java
│ │ ├── Semaphore.java
│ │ └── SimpleSchedulingExecutor.java
│ ├── dp
│ │ ├── CountBinarySubsequences.java
│ │ ├── EditDistance.java
│ │ ├── LongestCommonSubsequence.java
│ │ ├── PrintNeatly.java
│ │ ├── RatInAMaze.java
│ │ ├── RetrieveSentenceWithShuffledWords.java
│ │ └── RobotMove.java
│ ├── exceptions
│ │ └── EmptyHeapException.java
│ ├── general
│ │ ├── BinaryGap.java
│ │ ├── DigitSerializedArray.java
│ │ ├── EnglishKeyboard.java
│ │ ├── FindNumCombinations.java
│ │ ├── KnightsTour.java
│ │ ├── LexicographicalRanking.java
│ │ ├── MatrixRegionSum.java
│ │ ├── MaximalSum.java
│ │ ├── Maze.java
│ │ ├── MeetingRoom.java
│ │ ├── MergeIntervals.java
│ │ ├── MinimumMeetingRooms.java
│ │ ├── NQueens.java
│ │ ├── NextLexciographicalPermutation.java
│ │ ├── NextPalindromeNumber.java
│ │ ├── NumEvenSumPairs.java
│ │ ├── NumberOfZerosInFactorial.java
│ │ ├── PalindromeNumber.java
│ │ ├── PascalsTriangle.java
│ │ ├── PermutationsCombinations.java
│ │ ├── PowerFunctions.java
│ │ ├── PrimeFactors.java
│ │ ├── RainWater.java
│ │ ├── RatInAMaze.java
│ │ ├── RomanNumerals.java
│ │ ├── Schedule.java
│ │ ├── Shuffle.java
│ │ ├── SkylineOfACity.java
│ │ ├── SubsetSum.java
│ │ ├── ThreeSum.java
│ │ ├── Time.java
│ │ ├── TwoDifference.java
│ │ ├── TwoSum.java
│ │ └── YoungsTableau.java
│ ├── graphs
│ │ ├── BloodRelatives.java
│ │ ├── GraphNode.java
│ │ ├── SearchingTechniques.java
│ │ ├── SocialNetworkConnectivity.java
│ │ └── SpellChecker.java
│ ├── linkedlists
│ │ ├── List.java
│ │ └── SinglyLinkedList.java
│ ├── sorting
│ │ ├── FindMinLengthUnsortedSubArray.java
│ │ ├── Heap.java
│ │ ├── HeapSort.java
│ │ ├── InsertionSort.java
│ │ ├── KwayMerge.java
│ │ ├── MergeSort.java
│ │ ├── MergeWithSpaceForOtherArray.java
│ │ ├── QuickSort.java
│ │ ├── SimpleHeapImpl.java
│ │ ├── Sort012.java
│ │ └── StupidSort.java
│ ├── strings
│ │ ├── CheckInterleavedStrings.java
│ │ ├── LongestPalindromicSubstring.java
│ │ ├── LongestSubstringWithNoRepetition.java
│ │ ├── NaivePatternMatching.java
│ │ ├── RegexMatching.java
│ │ ├── SentenceReverse.java
│ │ └── StringSerialization.java
│ └── trees
│ │ ├── NaryTreeNode.java
│ │ ├── NaryTreeSerialization.java
│ │ └── SumTree.java
└── tests
│ ├── AllTests.java
│ ├── arrays
│ ├── RearrangeInputToTargetTest.java
│ └── SimplePhoneNumberAllotterTest.java
│ ├── binarytree
│ ├── BstClosestNodeTest.java
│ └── BstFindModeTest.java
│ ├── bitsandbytes
│ └── NumSetBitsTest.java
│ ├── cache
│ └── LRUCacheTest.java
│ ├── collections
│ ├── DeepIteratorTest.java
│ └── PeekIteratorTest.java
│ ├── common
│ └── NumberUtilsTest.java
│ ├── general
│ └── RainWaterTest.java
│ ├── lists
│ └── SinglyLinkedListTest.java
│ └── sorting
│ ├── HeapSortTest.java
│ ├── InsertionSortTest.java
│ ├── MergeSortTest.java
│ ├── QuickSortTest.java
│ ├── SimpleHeapImplTest.java
│ └── StupidSortTest.java
└── ruby
├── .idea
├── .name
├── encodings.xml
├── misc.xml
├── modules.xml
├── ruby.iml
├── scopes
│ └── scope_settings.xml
├── vcs.xml
└── workspace.xml
├── spec
├── .gitkeep
├── arrays
│ ├── sort_012_spec.rb
│ └── sub_array_with_max_sum_spec.rb
├── binary_trees
│ └── tree_to_circular_list_spec.rb
├── lists
│ └── singly_linked_list_spec.rb
├── sorting
│ ├── heap_sort_spec.rb
│ ├── merge_sort_spec.rb
│ ├── quick_sort_spec.rb
│ └── stupid_sort_spec.rb
└── spec_helper.rb
└── src
├── arrays
├── sort_012.rb
└── sub_array_with_max_sum.rb
├── binary_trees
├── tree_node.rb
└── tree_to_circular_list.rb
├── common
└── array_utils.rb
├── general
├── longest_palindromic_substring.rb
└── num_hops.rb
├── lists
└── singly_linked_list.rb
└── sorting
├── heap_sort.rb
├── merge_sort.rb
├── quick_sort.rb
└── stupid_sort.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | *~*
3 | *#*
4 | .metadata/
5 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | syringe
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/syringe.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DISCLAIMER:
--------------------------------------------------------------------------------
1 | Hi all,
2 |
3 | I am providing the code in this repository to you under the MIT license for open source projects.
4 | Because this is my personal repository, the license you receive to my code is from me and not from
5 | my employer (Facebook).
6 |
7 |
8 | Cheers,
9 | Kowshik Prakasam
10 | (kowshik@gmail.com)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Kowshik Prakasam
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Big O
2 | =====
3 |
4 | A big collection of data structures and algorithms puzzles.
5 | As on May 2013, the repository has roughly 130 problems with solutions.
6 |
7 | Solutions are primarily in Java (under [java/](https://github.com/kowshik/big-o/tree/master/java)). Some solutions are in Ruby (under [ruby/](https://github.com/kowshik/big-o/tree/master/ruby)).
8 |
9 | Problem statements are specified as Javadoc at the top of every solution. I have tried to be as descriptive as I can, but if something is not clear then please do let me know!
10 | Problems are broadly classified into the following categories which are self explanatory.
11 |
12 | Please feel free to contribute!
13 |
14 | * [arrays/](https://github.com/kowshik/big-o/tree/master/java/src/arrays)
15 | * [binarytrees/](https://github.com/kowshik/big-o/tree/master/java/src/binarytrees)
16 | * [bitsandbytes/](https://github.com/kowshik/big-o/tree/master/java/src/bitsandbytes)
17 | * [cache/](https://github.com/kowshik/big-o/tree/master/java/src/cache)
18 | * [collections/](https://github.com/kowshik/big-o/tree/master/java/src/collections)
19 | * [concurrency/](https://github.com/kowshik/big-o/tree/master/java/src/concurrency)
20 | * [dp/](https://github.com/kowshik/big-o/tree/master/java/src/dp)
21 | * [general/](https://github.com/kowshik/big-o/tree/master/java/src/general)
22 | * [graphs/](https://github.com/kowshik/big-o/tree/master/java/src/graphs)
23 | * [linkedlists/](https://github.com/kowshik/big-o/tree/master/java/src/linkedlists)
24 | * [sorting/](https://github.com/kowshik/big-o/tree/master/java/src/sorting)
25 | * [strings/](https://github.com/kowshik/big-o/tree/master/java/src/strings)
26 | * [trees/](https://github.com/kowshik/big-o/tree/master/java/src/trees)
27 |
28 |
29 |
--------------------------------------------------------------------------------
/java/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/java/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | big-o-java
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/java/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5 | org.eclipse.jdt.core.compiler.compliance=1.6
6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
11 | org.eclipse.jdt.core.compiler.source=1.6
12 |
--------------------------------------------------------------------------------
/java/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
3 | sp_cleanup.add_default_serial_version_id=true
4 | sp_cleanup.add_generated_serial_version_id=false
5 | sp_cleanup.add_missing_annotations=true
6 | sp_cleanup.add_missing_deprecated_annotations=true
7 | sp_cleanup.add_missing_methods=false
8 | sp_cleanup.add_missing_nls_tags=false
9 | sp_cleanup.add_missing_override_annotations=true
10 | sp_cleanup.add_missing_override_annotations_interface_methods=true
11 | sp_cleanup.add_serial_version_id=false
12 | sp_cleanup.always_use_blocks=true
13 | sp_cleanup.always_use_parentheses_in_expressions=false
14 | sp_cleanup.always_use_this_for_non_static_field_access=false
15 | sp_cleanup.always_use_this_for_non_static_method_access=false
16 | sp_cleanup.convert_to_enhanced_for_loop=false
17 | sp_cleanup.correct_indentation=true
18 | sp_cleanup.format_source_code=true
19 | sp_cleanup.format_source_code_changes_only=false
20 | sp_cleanup.make_local_variable_final=false
21 | sp_cleanup.make_parameters_final=false
22 | sp_cleanup.make_private_fields_final=true
23 | sp_cleanup.make_type_abstract_if_missing_method=false
24 | sp_cleanup.make_variable_declarations_final=true
25 | sp_cleanup.never_use_blocks=false
26 | sp_cleanup.never_use_parentheses_in_expressions=true
27 | sp_cleanup.on_save_use_additional_actions=true
28 | sp_cleanup.organize_imports=true
29 | sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
30 | sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
31 | sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
32 | sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
33 | sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
34 | sp_cleanup.remove_private_constructors=true
35 | sp_cleanup.remove_trailing_whitespaces=true
36 | sp_cleanup.remove_trailing_whitespaces_all=true
37 | sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
38 | sp_cleanup.remove_unnecessary_casts=true
39 | sp_cleanup.remove_unnecessary_nls_tags=false
40 | sp_cleanup.remove_unused_imports=false
41 | sp_cleanup.remove_unused_local_variables=false
42 | sp_cleanup.remove_unused_private_fields=true
43 | sp_cleanup.remove_unused_private_members=false
44 | sp_cleanup.remove_unused_private_methods=true
45 | sp_cleanup.remove_unused_private_types=true
46 | sp_cleanup.sort_members=false
47 | sp_cleanup.sort_members_all=false
48 | sp_cleanup.use_blocks=false
49 | sp_cleanup.use_blocks_only_for_return_and_throw=false
50 | sp_cleanup.use_parentheses_in_expressions=false
51 | sp_cleanup.use_this_for_non_static_field_access=false
52 | sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
53 | sp_cleanup.use_this_for_non_static_method_access=false
54 | sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
55 |
--------------------------------------------------------------------------------
/java/lib/junit-4.11.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kowshik/big-o/a5c5e5fad3049b8898b64b0952c9d7ac9fef9d1c/java/lib/junit-4.11.jar
--------------------------------------------------------------------------------
/java/src/arrays/Answer0toKRangeQuery.java:
--------------------------------------------------------------------------------
1 | package arrays;
2 |
3 | /**
4 | * Write a class that given an array of N integers with values in the range 0 to
5 | * K, pre-processes its input and then answers any query about how many of the N
6 | * integers fall into a range [A,B] in O(1) time (note: the range includes A and
7 | * B). Your algorithm can use no more than O(N + K) pre-preocessing time.
8 | *
9 | * Your class: Answer0toKRangeQuery should implement a constructor with the
10 | * following signature. The constructor should take as input the array to be
11 | * processed, and the value K which determines the range 0 to K.
12 | *
13 | * Answer0toKRangeQuery(int[] array, int k) {...}
14 | *
15 | * Your class should also implement the method:
16 | *
17 | * int countNumIntegers(int rangeStart, int rangeEnd) {...}
18 | *
19 | * The above method answers the required queries in O(1) time.
20 | */
21 | public class Answer0toKRangeQuery {
22 | private final int[] counter;
23 | private final int k;
24 |
25 | public Answer0toKRangeQuery(int[] array, int k) {
26 | if (k < 0) {
27 | throw new IllegalArgumentException(String.format(
28 | "Value of 'K' can't be negative. You passed: %d:", k));
29 | }
30 |
31 | this.k = k;
32 | counter = new int[k + 1];
33 | for (int number : array) {
34 | counter[number]++;
35 | }
36 |
37 | for (int i = 1; i <= k; i++) {
38 | counter[i] += counter[i - 1];
39 | }
40 | }
41 |
42 | public int countNumIntegers(int rangeStart, int rangeEnd) {
43 | if (rangeStart < 0) {
44 | throw new IllegalArgumentException(String.format(
45 | "rangeStart can't be negative. You passed: %d", rangeStart));
46 | }
47 |
48 | if (rangeEnd > k) {
49 | throw new IllegalArgumentException(String.format(
50 | "rangeStart can't be negative. You passed: %d", rangeEnd));
51 | }
52 |
53 | return counter[rangeEnd]
54 | - (rangeStart == 0 ? 0 : counter[rangeStart - 1]);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/java/src/arrays/CountInversions.java:
--------------------------------------------------------------------------------
1 | package arrays;
2 |
3 | /**
4 | * Count number of inversions in an array of integers.
5 | *
6 | * An inversion is a pair of indices: (i,j) such that i < j and array[i] >
7 | * array[j].
8 | *
9 | * Signature of expected method:
10 | *
11 | * public static long countInversions(int[] array) {...}
12 | */
13 | public class CountInversions {
14 | public static long countInversions(int[] array) {
15 | return countInversions(array, 0, array.length - 1,
16 | new int[array.length]);
17 | }
18 |
19 | // Recursively counts the inversions.
20 | private static long countInversions(int[] array, int start, int end,
21 | int[] merged) {
22 | if (start == end) {
23 | merged[0] = array[start];
24 | return 0L;
25 | }
26 |
27 | int middle = (start + end) / 2;
28 |
29 | int[] left = new int[middle - start + 1];
30 | long leftInversions = countInversions(array, start, middle, left);
31 | int[] right = new int[end - middle];
32 | long rightInversions = countInversions(array, middle + 1, end, right);
33 |
34 | return leftInversions + rightInversions
35 | + mergeAndCountInversions(left, right, merged);
36 | }
37 |
38 | // This method is very similar to merge sort's merge method. Study the
39 | // merge method first if you don't immediately understand the below.
40 | private static long mergeAndCountInversions(int[] foo, int[] bar,
41 | int[] merged) {
42 | if (foo == null || bar == null || merged == null) {
43 | throw new NullPointerException(
44 | "One or more of foo/bar/merged is null.");
45 | }
46 |
47 | long numInversions = 0L;
48 | int fooIndex = 0, barIndex = 0;
49 | int sortedIndex = 0;
50 | while (fooIndex < foo.length && barIndex < bar.length) {
51 | if (foo[fooIndex] <= bar[barIndex]) {
52 | merged[sortedIndex] = foo[fooIndex];
53 | fooIndex++;
54 | } else {
55 | numInversions += foo.length - fooIndex;
56 | merged[sortedIndex] = bar[barIndex];
57 | barIndex++;
58 | }
59 |
60 | sortedIndex++;
61 | }
62 |
63 | while (fooIndex < foo.length) {
64 | merged[sortedIndex] = foo[fooIndex];
65 | fooIndex++;
66 | sortedIndex++;
67 | }
68 |
69 | while (barIndex < bar.length) {
70 | merged[sortedIndex] = bar[barIndex];
71 | barIndex++;
72 | sortedIndex++;
73 | }
74 |
75 | return numInversions;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/java/src/arrays/FindCommonElements.java:
--------------------------------------------------------------------------------
1 | package arrays;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Find common elements between two sorted integer arrays.
8 | *
9 | * Signature of expected method:
10 | *
11 | * public static List findCommonElements(int[] a, int[] b) {...}
12 | */
13 | public class FindCommonElements {
14 | public static List findCommonElements(int[] a, int[] b) {
15 | if (a == null || b == null) {
16 | return null;
17 | }
18 |
19 | List common = new ArrayList();
20 | for (int aIndex = 0, bIndex = 0; aIndex < a.length && bIndex < b.length;) {
21 | if (a[aIndex] < b[bIndex]) {
22 | aIndex++;
23 | } else if (b[bIndex] < a[aIndex]) {
24 | bIndex++;
25 | } else {
26 | common.add(a[aIndex]);
27 | aIndex++;
28 | bIndex++;
29 | }
30 | }
31 |
32 | return common;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/java/src/arrays/FindNumHops.java:
--------------------------------------------------------------------------------
1 | package arrays;
2 |
3 | import java.util.HashSet;
4 | import java.util.Iterator;
5 | import java.util.Set;
6 |
7 | /**
8 | * You are given an array of size N containing *only* non-negative integers
9 | * (i.e. >= 0). From any index in the array, a hop can be either of the
10 | * following:
11 | *
12 | * [1] Jump array[index] positions
13 | * [2] Jump 1 position
14 | *
15 | * The target of this question is to find the number of hops required to reach
16 | * the last element in the array from the first element.
17 | *
18 | * Signature of expected method:
19 | *
20 | * public static int findNumHops(int[] array) {...}
21 | */
22 | public class FindNumHops {
23 | public static int findNumHops(int[] array) {
24 | if (array == null) {
25 | throw new NullPointerException("array can't be null.");
26 | }
27 |
28 | if (array.length == 0) {
29 | return 0;
30 | }
31 |
32 | Set steps = new HashSet();
33 | int lastSeenStep = array.length - 1;
34 | steps.add(lastSeenStep);
35 |
36 | for (int index = array.length - 2; index >= 0; index--) {
37 | int hopSize = array[index];
38 | int reachableStep = hopSize + index;
39 |
40 | if (steps.contains(reachableStep)) {
41 | for (Iterator iter = steps.iterator(); iter.hasNext();) {
42 | int step = iter.next();
43 | if (step < reachableStep) {
44 | iter.remove();
45 | }
46 | }
47 |
48 | steps.add(index);
49 | lastSeenStep = index;
50 | }
51 | }
52 |
53 | return steps.size() - 1 + lastSeenStep;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/java/src/arrays/RearrangeInputToTarget.java:
--------------------------------------------------------------------------------
1 | package arrays;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * You are given two integer arrays: input and target. These arrays contain the
8 | * same unique integers, and always the value zero in each of them. Also, the
9 | * target array is some permutation of the input array and both arrays are of
10 | * the same size.
11 | *
12 | * You are supposed to write a method to convert the input array to the target
13 | * array. The restriction is that you can modify the input array by repeating
14 | * only the following operation any number of times: Take any value in the input
15 | * array and swap its location with that of the value zero in the same array.
16 | *
17 | * Signature of expected method:
18 | *
19 | * public static void rearrange(int[] input, int[] target) {...}
20 | */
21 | public class RearrangeInputToTarget {
22 |
23 | public static void rearrange(int[] input, int[] target) {
24 | assert (input.length == target.length);
25 |
26 | Map map = new HashMap();
27 | buildIndex(input, map);
28 | int zeroIndex = common.ArrayUtils.findIndex(input, 0);
29 | int numMoves = 0;
30 |
31 | while (numMoves < input.length) {
32 | // zero has reached its final location. So we displace it
33 | // temporarily so that we can continue putting other elements in
34 | // their final locations.
35 | if (target[zeroIndex] == 0) {
36 | int outOfOrderIndex = findFirstOutOfOrderIndex(input, target);
37 | if (outOfOrderIndex == -1) {
38 | // All elements including '0' are in their final locations.
39 | return;
40 | }
41 |
42 | map.put(input[outOfOrderIndex], zeroIndex);
43 | // We need to update the index because we are going to modify
44 | // the original location of the value in input[outOfOrderIndex].
45 | common.ArrayUtils.swap(input, zeroIndex, outOfOrderIndex);
46 | zeroIndex = outOfOrderIndex;
47 |
48 | } else {
49 | // Swap zero with what should actually be in zero's location
50 | // in the target array.
51 | int nextZeroIndex = map.get(target[zeroIndex]);
52 | common.ArrayUtils.swap(input, zeroIndex, nextZeroIndex);
53 | zeroIndex = nextZeroIndex;
54 | numMoves++;
55 | }
56 | }
57 |
58 | }
59 |
60 | private static void buildIndex(int[] input, Map index) {
61 | for (int location = 0; location < input.length; location++) {
62 | index.put(input[location], location);
63 | }
64 | }
65 |
66 | private static int findFirstOutOfOrderIndex(int[] input, int[] target) {
67 | assert (input.length == target.length);
68 |
69 | for (int index = 0; index < input.length; index++) {
70 | if (input[index] != target[index]) {
71 | return index;
72 | }
73 | }
74 |
75 | return -1;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/java/src/binarytrees/BstClosestNode.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Given the root of a binary search tree and a node from the same tree, find
5 | * the node closest to the given node.
6 | *
7 | * Signature of expected method:
8 | *
9 | * public static TreeNode findClosestNode(TreeNode bstRootNode,
10 | * TreeNode node);
11 | */
12 | public class BstClosestNode {
13 | public static TreeNode findClosestNode(
14 | TreeNode bstRootNode, TreeNode node) {
15 | TreeNode inorderPredecessor = getInorderPredecessor(
16 | bstRootNode, node);
17 | TreeNode inorderSuccessor = getInorderSuccessor(bstRootNode,
18 | node);
19 |
20 | if (inorderPredecessor == null) {
21 | return inorderSuccessor;
22 | }
23 |
24 | if (inorderSuccessor == null) {
25 | return inorderPredecessor;
26 | }
27 |
28 | if ((node.getValue() - inorderPredecessor.getValue()) < (inorderSuccessor
29 | .getValue() - node.getValue())) {
30 | return inorderPredecessor;
31 | }
32 |
33 | return inorderSuccessor;
34 | }
35 |
36 | public static TreeNode getInorderSuccessor(
37 | TreeNode bstRootNode, TreeNode node) {
38 | if (bstRootNode == null || node == null) {
39 | return null;
40 | }
41 |
42 | TreeNode successorNode = getMinValueNode(node.getRight());
43 | if (successorNode != null) {
44 | return successorNode;
45 | }
46 |
47 | while (bstRootNode != null) {
48 | if (node.getValue() < bstRootNode.getValue()) {
49 | successorNode = bstRootNode;
50 | bstRootNode = bstRootNode.getLeft();
51 | } else {
52 | bstRootNode = bstRootNode.getRight();
53 | }
54 | }
55 |
56 | return successorNode;
57 | }
58 |
59 | public static TreeNode getInorderPredecessor(
60 | TreeNode bstRootNode, TreeNode node) {
61 | if (bstRootNode == null || node == null) {
62 | return null;
63 | }
64 |
65 | TreeNode predecessorNode = getMaxValueNode(node.getLeft());
66 | if (predecessorNode != null) {
67 | return predecessorNode;
68 | }
69 |
70 | while (bstRootNode != null) {
71 | if (node.getValue() > bstRootNode.getValue()) {
72 | predecessorNode = bstRootNode;
73 | bstRootNode = bstRootNode.getRight();
74 | } else {
75 | bstRootNode = bstRootNode.getLeft();
76 | }
77 | }
78 |
79 | return predecessorNode;
80 | }
81 |
82 | private static TreeNode getMinValueNode(TreeNode node) {
83 | if (node == null) {
84 | return null;
85 | }
86 |
87 | while (node.hasLeft()) {
88 | node = node.getLeft();
89 | }
90 |
91 | return node;
92 | }
93 |
94 | private static TreeNode getMaxValueNode(TreeNode node) {
95 | if (node == null) {
96 | return null;
97 | }
98 |
99 | while (node.hasRight()) {
100 | node = node.getRight();
101 | }
102 |
103 | return node;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/java/src/binarytrees/BstCountTrees.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Suppose you are building an N node binary search tree with the values 1..N.
5 | * How many structurally different binary search trees are there that store
6 | * those values? Write a recursive function that, given the number of distinct
7 | * values, computes the number of structurally unique binary search trees that
8 | * store those values.
9 | *
10 | * Signature of expected method:
11 | *
12 | * public static long countTrees(int numKeys);
13 | *
14 | * For example, countTrees(4) should return 14, since there
15 | * are 14 structurally unique binary search trees that store 1, 2, 3, and 4.
16 | */
17 | public class BstCountTrees {
18 |
19 | public static long countTrees(int numKeys) {
20 | if (numKeys <= 0) {
21 | return 0;
22 | }
23 |
24 | long sum = 0L;
25 | for (int root = 1; root <= numKeys; root++) {
26 | sum += countTrees(root - 1) * countTrees(numKeys - root);
27 | }
28 |
29 | return sum;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/java/src/binarytrees/BstDoubleTree.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * For each node in a binary search tree, create a new duplicate node, and
5 | * insert the duplicate as the left child of the original node. The resulting
6 | * tree should still be a binary search tree.
7 | *
8 | * Signature of expected method:
9 | *
10 | * public static void doubleTree(TreeNode root) {...}
11 | */
12 | public class BstDoubleTree {
13 | public static void doubleTree(TreeNode root) {
14 | if (root == null) {
15 | return;
16 | }
17 |
18 | doubleTree(root.getLeft());
19 | doubleTree(root.getRight());
20 |
21 | TreeNode duplicate = new TreeNode(root.getValue());
22 | duplicate.setLeft(root.getLeft());
23 | root.setLeft(duplicate);
24 |
25 | return;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/java/src/binarytrees/BstFindMode.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | import common.Pair;
4 |
5 | /**
6 | * Given a BST, find the mode i.e. the value that occurs maximum number of
7 | * times.
8 | *
9 | * Signature of expected method:
10 | *
11 | * public static T findMode(TreeNode root) {...}
12 | */
13 | public class BstFindMode {
14 | public static T findMode(TreeNode root) {
15 | Pair mode = new Pair();
16 | mode.setSecond(0);
17 |
18 | findMode(root, mode);
19 |
20 | return mode.getFirst();
21 | }
22 |
23 | private static void findMode(TreeNode root, Pair mode) {
24 | Pair current = new Pair();
25 | current.setSecond(0);
26 |
27 | findMode(root, mode, current);
28 | if (current.getFirst() != null
29 | && (mode.getFirst() == null || current.getSecond() > mode
30 | .getSecond())) {
31 | mode.setFirst(current.getFirst());
32 | mode.setSecond(current.getSecond());
33 | }
34 | }
35 |
36 | private static void findMode(TreeNode root, Pair mode,
37 | Pair current) {
38 | if (root == null) {
39 | return;
40 | }
41 |
42 | findMode(root.getLeft(), mode, current);
43 |
44 | if (current.getFirst() == null) {
45 | current.setFirst(root.getValue());
46 | current.setSecond(1);
47 | } else {
48 | if (current.getFirst().equals(root.getValue())) {
49 | current.setSecond(current.getSecond() + 1);
50 | } else {
51 | if (mode.getFirst() == null
52 | || current.getSecond() > mode.getSecond()) {
53 | mode.setFirst(current.getFirst());
54 | mode.setSecond(current.getSecond());
55 | }
56 |
57 | current.setFirst(root.getValue());
58 | current.setSecond(1);
59 | }
60 | }
61 |
62 | findMode(root.getRight(), mode, current);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/java/src/binarytrees/BstInsert.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | import java.util.Comparator;
4 |
5 | /**
6 | * Insert a value into a binary search tree.
7 | *
8 | * Signature of expected method:
9 | *
10 | * public static void insert(TreeNode root, T value,
11 | Comparator comparator) {...}
12 | *
13 | */
14 | public class BstInsert {
15 | public static void insert(TreeNode root, T value,
16 | Comparator comparator) {
17 | if (root == null || value == null || comparator == null) {
18 | return;
19 | }
20 |
21 | doInsert(root, value, comparator);
22 | }
23 |
24 | private static TreeNode doInsert(TreeNode root, T value,
25 | Comparator comparator) {
26 | if (root == null) {
27 | return new TreeNode(value);
28 | }
29 |
30 | if (comparator.compare(root.getValue(), value) <= 0) {
31 | root.setLeft(doInsert(root.getLeft(), value, comparator));
32 | }
33 |
34 | root.setRight(doInsert(root.getRight(), value, comparator));
35 | return root;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/java/src/binarytrees/BstIsBst.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Check if a binary tree is a binary search tree. To keep things simple, assume
5 | * that the binary tree contains only integers.
6 | *
7 | * Signature of expected method:
8 | *
9 | * public static boolean isBst(TreeNode rootNode) {...}
10 | */
11 | public class BstIsBst {
12 | public static boolean isBst(TreeNode rootNode) {
13 | return isBst(rootNode, Integer.MIN_VALUE, Integer.MAX_VALUE);
14 | }
15 |
16 | private static boolean isBst(TreeNode rootNode, int minValue,
17 | int maxValue) {
18 | if (rootNode == null) {
19 | return true;
20 | }
21 |
22 | boolean check = minValue <= rootNode.getValue()
23 | && rootNode.getValue() < maxValue;
24 | if (check) {
25 | check = isBst(rootNode.getLeft(), minValue, rootNode.getValue());
26 | if (check) {
27 | check = isBst(rootNode.getRight(), rootNode.getValue() + 1,
28 | maxValue);
29 | }
30 | }
31 |
32 | return check;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/java/src/binarytrees/BstLookup.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | import java.util.Comparator;
4 |
5 | /**
6 | * Check if a given node exists in the binary search tree.
7 | *
8 | * Signature of expected method:
9 | *
10 | * public static boolean lookup(TreeNode rootNode,
11 | TreeNode searchedNode, Comparator comparator) {...}
12 | */
13 | public class BstLookup {
14 | public static boolean lookup(TreeNode rootNode,
15 | TreeNode searchedNode, Comparator comparator) {
16 | if (rootNode == null) {
17 | return false;
18 | }
19 |
20 | int compared = comparator.compare(rootNode.getValue(),
21 | searchedNode.getValue());
22 | if (compared < 0) {
23 | return lookup(rootNode.getLeft(), searchedNode, comparator);
24 | } else if (compared == 0) {
25 | return true;
26 | }
27 |
28 | return lookup(rootNode.getRight(), searchedNode, comparator);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/java/src/binarytrees/BstMinValue.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Find the smallest value in a binary search tree.
5 | *
6 | * Signature of expected method:
7 | *
8 | * public static T minValue(TreeNode root) {...}
9 | */
10 | public class BstMinValue {
11 | public static T minValue(TreeNode root) {
12 | if (root == null) {
13 | return null;
14 | }
15 |
16 | while (root.getLeft() != null) {
17 | root = root.getLeft();
18 | }
19 |
20 | return root.getValue();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeConvertToSinglyLinkedList.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | import common.Pair;
4 |
5 | /**
6 | * Given a binary tree, convert it into a singly linked list. The "next" pointer
7 | * in each node of the list is defined using the "right" pointer in the binary
8 | * tree. The order of nodes in the linked list is the same order that occurs in
9 | * the inorder representation of the binary tree. Also the solution must set all
10 | * "left" pointers in each node to null.
11 | *
12 | * Signature of expected method:
13 | *
14 | * public static TreeNode convertToSinglyLinkedList(
15 | TreeNode root) {...}
16 | */
17 | public class TreeConvertToSinglyLinkedList {
18 | public static TreeNode convertToSinglyLinkedList(
19 | TreeNode root) {
20 | return doConnectInorder(root).getFirst();
21 | }
22 |
23 | private static Pair, TreeNode> doConnectInorder(
24 | TreeNode root) {
25 | if (root == null) {
26 | return null;
27 | }
28 |
29 | Pair, TreeNode> toReturn = new Pair, TreeNode>();
30 | Pair, TreeNode> leftPair = doConnectInorder(root
31 | .getLeft());
32 | if (leftPair != null) {
33 | leftPair.getSecond().setRight(root);
34 | toReturn.setFirst(leftPair.getFirst());
35 | } else {
36 | toReturn.setFirst(root);
37 | }
38 |
39 | Pair, TreeNode> rightPair = doConnectInorder(root
40 | .getRight());
41 | if (rightPair != null) {
42 | root.setRight(rightPair.getFirst());
43 | toReturn.setSecond(rightPair.getSecond());
44 | } else {
45 | toReturn.setSecond(root);
46 | }
47 |
48 | root.setLeft(null);
49 |
50 | return toReturn;
51 | }
52 |
53 | public static void main(String[] args) {
54 | TreeNode rootLeftLeft = new TreeNode(3);
55 | TreeNode rootLeftRight = new TreeNode(5);
56 |
57 | TreeNode rootLeft = new TreeNode(4);
58 | rootLeft.setLeft(rootLeftLeft);
59 | rootLeft.setRight(rootLeftRight);
60 |
61 | TreeNode rootRightLeft = new TreeNode(7);
62 | TreeNode rootRightRight = new TreeNode(9);
63 |
64 | TreeNode rootRight = new TreeNode(8);
65 | rootRight.setLeft(rootRightLeft);
66 | rootRight.setRight(rootRightRight);
67 |
68 | TreeNode root = new TreeNode(6);
69 | root.setLeft(rootLeft);
70 | root.setRight(rootRight);
71 |
72 | root = convertToSinglyLinkedList(root);
73 |
74 | while (root != null) {
75 | System.out.println(root);
76 | System.out.println(root.getLeft());
77 | root = root.getRight();
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeDepth.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Given a binary tree, find its depth.
5 | *
6 | * Signature of expected method:
7 | *
8 | * public static int maxDepth(TreeNode> root) {...}
9 | */
10 | public class TreeDepth {
11 | public static int maxDepth(TreeNode> root) {
12 | if (root == null) {
13 | return 0;
14 | }
15 |
16 | return Math.max(maxDepth(root.getLeft()), maxDepth(root.getRight())) + 1;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeHasPathSum.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Given a binary tree and a sum, return true if the tree has a root-to-leaf
5 | * path such that adding up all the values along the path equals the given sum.
6 | * Return false if no such path can be found.
7 | *
8 | * Signature of expected method:
9 | *
10 | * public static boolean hasPathSum(TreeNode root, int sum) {...}
11 | */
12 | public class TreeHasPathSum {
13 | public static boolean hasPathSum(TreeNode root, int sum) {
14 | if (root == null) {
15 | return false;
16 | }
17 |
18 | Integer value = root.getValue();
19 | if (value == null) {
20 | throw new NullPointerException("You are an insane programmer.");
21 | }
22 | return hasPathSum(root.getLeft(), sum - value)
23 | || hasPathSum(root.getRight(), sum - value)
24 | || (sum - value == 0 && !root.hasLeft() && !root.hasRight());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeMirror.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Given a binary tree, convert it into its mirror.
5 | *
6 | * Signature of expected method:
7 | *
8 | * public static void mirror(TreeNode root) {
9 | */
10 | public class TreeMirror {
11 | public static void mirror(TreeNode root) {
12 | if (root == null) {
13 | return;
14 | }
15 |
16 | mirror(root.getLeft());
17 | mirror(root.getRight());
18 |
19 | TreeNode temp = root.getLeft();
20 | root.setLeft(root.getRight());
21 | root.setRight(temp);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeNode.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | public class TreeNode {
4 | private TreeNode left;
5 | private TreeNode right;
6 | private T value;
7 |
8 | public TreeNode(T value) {
9 | setValue(value);
10 | }
11 |
12 | public TreeNode getLeft() {
13 | return left;
14 | }
15 |
16 | public void setLeft(TreeNode left) {
17 | this.left = left;
18 | }
19 |
20 | public TreeNode getRight() {
21 | return right;
22 | }
23 |
24 | public boolean hasLeft() {
25 | return getLeft() != null;
26 | }
27 |
28 | public void setRight(TreeNode right) {
29 | this.right = right;
30 | }
31 |
32 | public boolean hasRight() {
33 | return getRight() != null;
34 | }
35 |
36 | public T getValue() {
37 | return value;
38 | }
39 |
40 | public void setValue(T value) {
41 | this.value = value;
42 | }
43 |
44 | public boolean hasValue() {
45 | return getValue() != null;
46 | }
47 |
48 | @Override
49 | public String toString() {
50 | if (getValue() != null) {
51 | return getValue().toString();
52 | }
53 |
54 | return "";
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreePrintPaths.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | import java.util.LinkedList;
4 |
5 | /**
6 | * Given the root of a binary tree, print all different paths from root to
7 | * leaves to standard out.
8 | *
9 | * Signature of expected method:
10 | *
11 | * public static void printPaths(TreeNode> root) {...}
12 | */
13 | public class TreePrintPaths {
14 | public static void printPaths(TreeNode> root) {
15 | @SuppressWarnings("rawtypes")
16 | LinkedList list = new LinkedList();
17 | printPaths(root, list);
18 | }
19 |
20 | @SuppressWarnings("unchecked")
21 | private static void printPaths(TreeNode> root,
22 | @SuppressWarnings("rawtypes") LinkedList path) {
23 | if (root == null) {
24 | return;
25 | }
26 |
27 | Object value = root.getValue();
28 | path.addLast(value);
29 | printPaths(root.getLeft(), path);
30 | printPaths(root.getRight(), path);
31 |
32 | if (root.getLeft() == null && root.getRight() == null) {
33 | System.out.println(path);
34 | }
35 |
36 | path.removeLast();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeReconstruct.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | import java.util.Comparator;
4 |
5 | /**
6 | * Reconstruct a binary tree from its inorder and preorder traversals.
7 | *
8 | * Signature of expected method:
9 | *
10 | * public static TreeNode reconstruct(T[] inorder, T[] preorder,
11 | * Comparator comparator) {...}
12 | */
13 |
14 | public class TreeReconstruct {
15 |
16 | public static TreeNode reconstruct(T[] inorder, T[] preorder,
17 | Comparator comparator) {
18 | return reconstruct(inorder, 0, inorder.length - 1, preorder, 0,
19 | preorder.length - 1, comparator);
20 | }
21 |
22 | private static TreeNode reconstruct(T[] inorder, int inorderStart,
23 | int inorderEnd, T[] preorder, int preorderStart, int preorderEnd,
24 | Comparator comparator) {
25 | if (inorderStart > inorderEnd || preorderStart > preorderEnd) {
26 | return null;
27 | }
28 |
29 | int rootNodeIndex = findNode(inorder, inorderStart, inorderEnd,
30 | preorder[preorderStart], comparator);
31 | if (rootNodeIndex == -1) {
32 | throw new RuntimeException("Bad input.");
33 | }
34 |
35 | TreeNode rootNode = new TreeNode(inorder[rootNodeIndex]);
36 |
37 | int leftSubTreeSize = rootNodeIndex - inorderStart;
38 | TreeNode leftNode = reconstruct(inorder, inorderStart,
39 | rootNodeIndex - 1, preorder, preorderStart + 1, preorderStart
40 | + leftSubTreeSize, comparator);
41 |
42 | TreeNode rightNode = reconstruct(inorder, rootNodeIndex + 1,
43 | inorderEnd, preorder, preorderStart + leftSubTreeSize + 1,
44 | preorderEnd, comparator);
45 |
46 | rootNode.setLeft(leftNode);
47 | rootNode.setRight(rightNode);
48 | return rootNode;
49 | }
50 |
51 | private static int findNode(T[] array, int startIndex, int endIndex,
52 | T value, Comparator comparator) {
53 | for (int index = startIndex; index <= endIndex; index++) {
54 | if (comparator.compare(array[index], value) == 0) {
55 | return index;
56 | }
57 | }
58 |
59 | return -1;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeRecursiveTraversals.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Given the root of a binary tree recursively print the (in/pre/post)-order
5 | * traversals to standard out.
6 | *
7 | * Signature of expected methods:
8 | *
9 | * public static void inorderTraversal(TreeNode root) {...}
10 | * public static void preorderTraversal(TreeNode root) {...}
11 | * public static void postorderTraversal(TreeNode root) {...}
12 | */
13 | public class TreeRecursiveTraversals {
14 |
15 | public static void inorderTraversal(TreeNode root) {
16 | if (root == null) {
17 | return;
18 | }
19 |
20 | inorderTraversal(root.getLeft());
21 | System.out.printf("%s ", root.getValue());
22 | inorderTraversal(root.getRight());
23 | }
24 |
25 | public static void preorderTraversal(TreeNode root) {
26 | if (root == null) {
27 | return;
28 | }
29 |
30 | System.out.printf("%s ", root.getValue());
31 | preorderTraversal(root.getLeft());
32 | preorderTraversal(root.getRight());
33 | }
34 |
35 | public static void postorderTraversal(TreeNode root) {
36 | if (root == null) {
37 | return;
38 | }
39 |
40 | postorderTraversal(root.getLeft());
41 | postorderTraversal(root.getRight());
42 | System.out.printf("%s ", root.getValue());
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeSameTree.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | import java.util.Comparator;
4 |
5 | /**
6 | * Determine if two binary trees are structurally identical.
7 | *
8 | * Signature of expected method:
9 | *
10 | * public static boolean isSameTree(TreeNode rootFoo,
11 | TreeNode rootBar,
12 | Comparator comparator) {...}
13 | */
14 | public class TreeSameTree {
15 | public static boolean isSameTree(TreeNode rootFoo,
16 | TreeNode rootBar, Comparator comparator) {
17 | if (rootFoo == null && rootBar == null) {
18 | return true;
19 | }
20 |
21 | if (rootFoo != null && rootBar != null) {
22 | return isSameTree(rootFoo.getLeft(), rootBar.getLeft(), comparator)
23 | && isSameTree(rootFoo.getRight(), rootBar.getRight(),
24 | comparator)
25 | && comparator.compare(rootFoo.getValue(),
26 | rootBar.getValue()) == 0;
27 | }
28 |
29 | return false;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/java/src/binarytrees/TreeSize.java:
--------------------------------------------------------------------------------
1 | package binarytrees;
2 |
3 | /**
4 | * Find the size of a binary tree.
5 | *
6 | * Signature of expected method:
7 | *
8 | * public static int size(TreeNode> root) {...}
9 | */
10 | public class TreeSize {
11 | public static int size(TreeNode> root) {
12 | if (root == null) {
13 | return 0;
14 | }
15 |
16 | return size(root.getLeft()) + 1 + size(root.getRight());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/java/src/bitsandbytes/NumSetBits.java:
--------------------------------------------------------------------------------
1 | package bitsandbytes;
2 |
3 | /**
4 | * You have a series of LEDs whose state is represented as a series of bits -- 1
5 | * represents ON and 0 represents off. You are also given an offset and a
6 | * length. You need to find the number of LED bulbs present in ON state,
7 | * starting at the specified offset in the series of bits, until the specified
8 | * length from the offset. Write the method signature and code in any language.
9 | *
10 | * Signature of expected method:
11 | *
12 | * public static long getNumSetBits(byte[] leds, long offset, long length) {...}
13 | *
14 | */
15 | public class NumSetBits {
16 | public static long getNumSetBits(byte[] leds, long offset, long length) {
17 | // s/offset/firstBitIndex/ for readability.
18 | long firstBitIndex = offset;
19 | long lastBitIndex = firstBitIndex + length - 1;
20 | byte firstByteIndex = (byte) (firstBitIndex / 8);
21 | byte lastByteIndex = (byte) ((firstBitIndex + length - 1) / 8);
22 |
23 | long totalSetBits = 0L;
24 | if (firstByteIndex != lastByteIndex) {
25 | totalSetBits += getNumSetBitsBetweenWholeBytes(leds,
26 | firstByteIndex + 1, lastByteIndex - 1);
27 | totalSetBits += getNumSetBits(leds[firstByteIndex],
28 | (int) (firstBitIndex % 8), 7);
29 | totalSetBits += getNumSetBits(leds[lastByteIndex], 0,
30 | (int) (lastBitIndex % 8));
31 | } else {
32 | totalSetBits += getNumSetBits(leds[firstByteIndex],
33 | (int) (firstBitIndex % 8), (int) (lastBitIndex % 8));
34 | }
35 |
36 | return totalSetBits;
37 | }
38 |
39 | public static int getNumSetBits(byte b, int startOffset, int endOffset) {
40 | if ((startOffset < 0 || startOffset > 7)
41 | || (endOffset < 0 || endOffset > 7) || endOffset < startOffset) {
42 | throw new IllegalArgumentException(String.format(
43 | "Either startOffset: %d or endOffset: %d is incorrect",
44 | startOffset, endOffset));
45 | }
46 |
47 | int totalBits = 0;
48 | for (int bitIndex = startOffset; bitIndex <= endOffset; bitIndex++) {
49 | totalBits += (byte) (b & (1 << (8 - bitIndex - 1))) != 0 ? 1 : 0;
50 | }
51 |
52 | return totalBits;
53 | }
54 |
55 | public static long getNumSetBitsBetweenWholeBytes(byte[] array,
56 | int firstByte, int lastByte) {
57 | long totalBits = 0;
58 | for (int index = firstByte; index <= lastByte; index++) {
59 | totalBits += getNumSetBits(array[index], 0, 7);
60 | }
61 |
62 | return totalBits;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/java/src/cache/Cache.java:
--------------------------------------------------------------------------------
1 | package cache;
2 |
3 | /**
4 | * A simple cache interface.
5 | *
6 | * @param
7 | * Type of cache key
8 | * @param
9 | * Type of cache value
10 | */
11 | public interface Cache {
12 | CacheValueType get(CacheKeyType key);
13 |
14 | void put(CacheKeyType key, CacheValueType value);
15 |
16 | int getSize();
17 | }
18 |
--------------------------------------------------------------------------------
/java/src/collections/FilteringIterator.java:
--------------------------------------------------------------------------------
1 | package collections;
2 |
3 | import java.util.Iterator;
4 | import java.util.NoSuchElementException;
5 |
6 | /**
7 | * Implement an iterator that filters elements from the underlying iterator
8 | * based on the given predicate.
9 | *
10 | * Methods expected to be implemented:
11 | *
12 | * public class FilteringIterator implements Iterator {
13 | * public FilteringIterator(Iterator iterator,
14 | * Predicate predicate) {...}
15 | * public boolean hasNext() {...}
16 | * public T next() {...}
17 | * }
18 | */
19 |
20 | interface Predicate {
21 | boolean apply(T object);
22 | }
23 |
24 | public class FilteringIterator implements Iterator {
25 |
26 | private final Iterator iterator;
27 | private final Predicate predicate;
28 | private T nextItem;
29 |
30 | public FilteringIterator(Iterator iterator, Predicate predicate) {
31 | this.iterator = iterator;
32 | this.predicate = predicate;
33 | nextItem = null;
34 | }
35 |
36 | @Override
37 | public boolean hasNext() {
38 | if (nextItem != null) {
39 | return true;
40 | }
41 |
42 | while (iterator.hasNext()) {
43 | T item = iterator.next();
44 | if (predicate.apply(item)) {
45 | nextItem = item;
46 | break;
47 | }
48 | }
49 |
50 | return nextItem != null;
51 | }
52 |
53 | @Override
54 | public T next() {
55 | if (!hasNext()) {
56 | throw new NoSuchElementException();
57 | }
58 |
59 | T toReturn = nextItem;
60 | nextItem = null;
61 | return toReturn;
62 | }
63 |
64 | @Override
65 | public void remove() {
66 | throw new UnsupportedOperationException();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/java/src/collections/HoppingIterator.java:
--------------------------------------------------------------------------------
1 | package collections;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Iterator;
5 | import java.util.List;
6 | import java.util.NoSuchElementException;
7 |
8 | /**
9 | * Implement an iterator that hops specified number of times and then returns the next
10 | * element after the hop. Note: the iterator always returns the first element as
11 | * it is, and starts hopping only after the first element.
12 | *
13 | * Examples:
14 | *
15 | * If the original iterator returns: [1, 2, 3, 4, 5] in order, then the hopping
16 | * iterator will return [1, 3, 5] in order when the hop value is 1.
17 | *
18 | * If the original iterator returns: [1, 2, 3, 4, 5] in order, then the hopping
19 | * iterator will return [1, 4] in order when the hop value is 2.
20 | *
21 | * If the original iterator returns: [1, 2, 3, 4, 5] in order, then the hopping
22 | * iterator will return [1, 5] in order when the hop value is 3.
23 | *
24 | * Methods expected to be implemented:
25 | *
26 | * public class HoppingIterator implements Iterator {
27 | * public HoppingIterator(Iterator iterator, int numHops) {...}
28 | * public boolean hasNext() {...}
29 | * public T next() {...}
30 | * }
31 | */
32 | public class HoppingIterator implements Iterator {
33 |
34 | private final Iterator iterator;
35 | private T nextItem;
36 | private final int numHops;
37 | private boolean first;
38 |
39 | public HoppingIterator(Iterator iterator, int numHops) {
40 | if (numHops < 0) {
41 | throw new IllegalArgumentException(String.format(
42 | "numHops needs to be >= 0. You passed: %d", numHops));
43 | }
44 |
45 | this.numHops = numHops;
46 | this.iterator = iterator;
47 | nextItem = null;
48 | first = true;
49 | }
50 |
51 | @Override
52 | public boolean hasNext() {
53 | if (nextItem != null) {
54 | return true;
55 | }
56 |
57 | if (!first) {
58 | for (int hop = 0; hop < numHops && iterator.hasNext(); hop++) {
59 | iterator.next();
60 | }
61 | }
62 |
63 | if (iterator.hasNext()) {
64 | nextItem = iterator.next();
65 | first = false;
66 | }
67 |
68 | return nextItem != null;
69 | }
70 |
71 | @Override
72 | public T next() {
73 | if (!hasNext()) {
74 | throw new NoSuchElementException();
75 | }
76 |
77 | T toReturn = nextItem;
78 | nextItem = null;
79 | return toReturn;
80 | }
81 |
82 | @Override
83 | public void remove() {
84 | throw new UnsupportedOperationException();
85 | }
86 |
87 | public static void main(String[] args) {
88 | List list = new ArrayList();
89 | list.add(1);
90 | list.add(2);
91 | list.add(3);
92 | list.add(4);
93 | list.add(5);
94 |
95 | HoppingIterator hi = new HoppingIterator(
96 | list.iterator(), 2);
97 | System.out.println(hi.next());
98 | System.out.println(hi.next());
99 | System.out.println(hi.hasNext());
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/java/src/collections/InorderIterator.java:
--------------------------------------------------------------------------------
1 | package collections;
2 |
3 | import java.util.Iterator;
4 | import java.util.NoSuchElementException;
5 | import java.util.Stack;
6 |
7 | import binarytrees.TreeNode;
8 |
9 | /**
10 | * Implement an iterator that iterates through a binary tree in inorder.
11 | *
12 | * Methods expected to be implemented:
13 | *
14 | * public class InorderIterator implements Iterator {
15 | * public InorderIterator(TreeNode rootNode) {...}
16 | * public boolean hasNext() {...}
17 | * public T next() {...}
18 | * }
19 | */
20 | public class InorderIterator implements Iterator {
21 | private T nextItem;
22 | private final Stack> stack;
23 | private boolean unwind;
24 |
25 | public InorderIterator(TreeNode rootNode) {
26 | this.nextItem = null;
27 | this.stack = new Stack>();
28 | stack.push(rootNode);
29 | }
30 |
31 | @Override
32 | public boolean hasNext() {
33 | if (nextItem != null) {
34 | return true;
35 | }
36 |
37 | if (stack.empty()) {
38 | return false;
39 | }
40 |
41 | TreeNode node;
42 | if (!unwind) {
43 | while ((node = stack.peek()).hasLeft()) {
44 | stack.push(node.getLeft());
45 | }
46 | }
47 |
48 | node = stack.pop();
49 | nextItem = node.getValue();
50 |
51 | if (node.hasRight()) {
52 | unwind = false;
53 | stack.push(node.getRight());
54 | } else {
55 | unwind = true;
56 | }
57 |
58 | return true;
59 | }
60 |
61 | @Override
62 | public T next() {
63 | if (!hasNext()) {
64 | throw new NoSuchElementException();
65 | }
66 |
67 | T toReturn = nextItem;
68 | nextItem = null;
69 | return toReturn;
70 | }
71 |
72 | @Override
73 | public void remove() {
74 | throw new UnsupportedOperationException();
75 | }
76 |
77 | // Some quick testing below.
78 | public static void main(String[] args) {
79 | TreeNode ll = new TreeNode(1);
80 | TreeNode l = new TreeNode(2);
81 |
82 | TreeNode r = new TreeNode(5);
83 | TreeNode rl = new TreeNode(4);
84 | TreeNode rr = new TreeNode(6);
85 |
86 | l.setLeft(ll);
87 |
88 | r.setLeft(rl);
89 | r.setRight(rr);
90 |
91 | TreeNode rootNode = new TreeNode(3);
92 | rootNode.setLeft(l);
93 | rootNode.setRight(r);
94 |
95 | InorderIterator ii = new InorderIterator(rootNode);
96 |
97 | System.out.println(ii.next());
98 | System.out.println(ii.hasNext());
99 | System.out.println(ii.next());
100 | System.out.println(ii.hasNext());
101 | System.out.println(ii.next());
102 | System.out.println(ii.hasNext());
103 | System.out.println(ii.next());
104 | System.out.println(ii.hasNext());
105 | System.out.println(ii.next());
106 | System.out.println(ii.hasNext());
107 | System.out.println(ii.next());
108 | System.out.println(ii.hasNext());
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/java/src/collections/LevelOrderIterator.java:
--------------------------------------------------------------------------------
1 | package collections;
2 |
3 | import java.util.Iterator;
4 | import java.util.LinkedList;
5 | import java.util.NoSuchElementException;
6 | import java.util.Queue;
7 |
8 | import binarytrees.TreeNode;
9 |
10 | /**
11 | * Implement an iterator that iterates through a binary tree in level order.
12 | *
13 | * Methods expected to be implemented:
14 | *
15 | * public class LevelOrderIterator implements Iterator {
16 | * public LevelOrderIterator(TreeNode rootNode) {..}
17 | * public boolean hasNext() {...}
18 | * public T next() {...}
19 | * }
20 | */
21 | public class LevelOrderIterator implements Iterator {
22 |
23 | private T nextItem;
24 | private final Queue> queue;
25 |
26 | public LevelOrderIterator(TreeNode rootNode) {
27 | queue = new LinkedList>();
28 | queue.add(rootNode);
29 | }
30 |
31 | @Override
32 | public boolean hasNext() {
33 | if (nextItem != null) {
34 | return true;
35 | }
36 |
37 | if (queue.isEmpty()) {
38 | return false;
39 | }
40 |
41 | TreeNode node = queue.remove();
42 | if (node.hasLeft()) {
43 | queue.add(node.getLeft());
44 | }
45 |
46 | if (node.hasRight()) {
47 | queue.add(node.getRight());
48 | }
49 |
50 | nextItem = node.getValue();
51 | return true;
52 | }
53 |
54 | @Override
55 | public T next() {
56 | if (!hasNext()) {
57 | throw new NoSuchElementException();
58 | }
59 |
60 | T toReturn = nextItem;
61 | nextItem = null;
62 | return toReturn;
63 | }
64 |
65 | @Override
66 | public void remove() {
67 | throw new UnsupportedOperationException();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/java/src/collections/MaxIterator.java:
--------------------------------------------------------------------------------
1 | package collections;
2 |
3 | import java.util.Comparator;
4 | import java.util.Iterator;
5 | import java.util.NoSuchElementException;
6 | import java.util.Vector;
7 |
8 | /**
9 | * Implement a max iterator i.e. it always returns the next item in the list
10 | * bigger than the last item returned.
11 | *
12 | * Methods expected to be implemented:
13 | *
14 | * public class MaxIterator implements Iterator {
15 | * public MaxIterator(Iterator iterator, Comparator comparator) {..}
16 | * public boolean hasNext() {...}
17 | * public T next() {...}
18 | * }
19 | */
20 | public class MaxIterator implements Iterator {
21 |
22 | private final Iterator iterator;
23 | private T nextItem;
24 | private T lastItem;
25 | private final Comparator comparator;
26 |
27 | public MaxIterator(Iterator iterator, Comparator comparator) {
28 | this.iterator = iterator;
29 | this.comparator = comparator;
30 | }
31 |
32 | @Override
33 | public boolean hasNext() {
34 | if (nextItem != null) {
35 | return true;
36 | }
37 |
38 | while (nextItem == null && iterator.hasNext()) {
39 | T item = iterator.next();
40 | if (lastItem == null || comparator.compare(item, lastItem) > 0) {
41 | nextItem = item;
42 | }
43 | }
44 |
45 | return nextItem != null;
46 | }
47 |
48 | @Override
49 | public T next() {
50 | if (!hasNext()) {
51 | throw new NoSuchElementException();
52 | }
53 |
54 | lastItem = nextItem;
55 | nextItem = null;
56 | return lastItem;
57 | }
58 |
59 | @Override
60 | public void remove() {
61 | throw new UnsupportedOperationException();
62 | }
63 |
64 | public static void main(String[] args) {
65 | Vector vec = new Vector();
66 | vec.add(3);
67 | vec.add(2);
68 | vec.add(9);
69 | vec.add(8);
70 | vec.add(11);
71 |
72 | MaxIterator mi = new MaxIterator(vec.iterator(),
73 | new Comparator() {
74 | @Override
75 | public int compare(Integer a, Integer b) {
76 | return a - b;
77 | }
78 | });
79 |
80 | System.out.println(mi.next());
81 | System.out.println(mi.next());
82 | System.out.println(mi.next());
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/java/src/collections/PeekIterator.java:
--------------------------------------------------------------------------------
1 | package collections;
2 |
3 | import java.util.Iterator;
4 | import java.util.NoSuchElementException;
5 |
6 | /**
7 | * Implement a peeking iterator. This can be used to peek at values
8 | * in the underlying iterator before iterating over them.
9 | *
10 | * Methods expected to be implemented:
11 | *
12 | * public class PeekIterator implements Iterator {
13 | * public PeekIterator(Iterator iterator) {...}
14 | * public boolean hasNext() {...}
15 | * public T next() {...}
16 | * }
17 | */
18 | public class PeekIterator implements Iterator {
19 |
20 | private final Iterator iterator;
21 | private T nextitem;
22 |
23 | public PeekIterator(Iterator iterator) {
24 | this.iterator = iterator;
25 | }
26 |
27 | @Override
28 | public boolean hasNext() {
29 | if (nextitem != null) {
30 | return true;
31 | }
32 |
33 | if (iterator.hasNext()) {
34 | nextitem = iterator.next();
35 | }
36 |
37 | return nextitem != null;
38 | }
39 |
40 | @Override
41 | public T next() {
42 | if (!hasNext()) {
43 | throw (new NoSuchElementException("Iterator has no elements left."));
44 | }
45 |
46 | T toReturn = nextitem;
47 | nextitem = null;
48 | return toReturn;
49 | }
50 |
51 | public T peek() {
52 | if (!hasNext()) {
53 | throw (new NoSuchElementException("Iterator has no elements left."));
54 | }
55 |
56 | return nextitem;
57 | }
58 |
59 | @Override
60 | public void remove() {
61 | throw new UnsupportedOperationException();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/java/src/collections/PreorderIterator.java:
--------------------------------------------------------------------------------
1 | package collections;
2 |
3 | import java.util.Iterator;
4 | import java.util.NoSuchElementException;
5 | import java.util.Stack;
6 |
7 | import binarytrees.TreeNode;
8 |
9 | /**
10 | * Implement an iterator that iterates through a binary tree in preorder.
11 | *
12 | * Methods expected to be implemented:
13 | *
14 | * public class PreorderIterator implements Iterator {
15 | * public PreorderIterator(TreeNode rootNode) {...}
16 | * public boolean hasNext() {...}
17 | * public T next() {...}
18 | * }
19 | */
20 | public class PreorderIterator implements Iterator {
21 | private T nextItem;
22 | private final Stack> stack;
23 |
24 | public PreorderIterator(TreeNode rootNode) {
25 | this.nextItem = null;
26 | this.stack = new Stack>();
27 | stack.push(rootNode);
28 | }
29 |
30 | @Override
31 | public boolean hasNext() {
32 | if (nextItem != null) {
33 | return true;
34 | }
35 |
36 | if (stack.empty()) {
37 | return false;
38 | }
39 |
40 | TreeNode node = stack.peek();
41 | nextItem = node.getValue();
42 | if (node.hasLeft()) {
43 | stack.push(node.getLeft());
44 | } else {
45 | while (!stack.empty()) {
46 | TreeNode current = stack.pop();
47 | if (current.hasRight()) {
48 | stack.push(current.getRight());
49 | break;
50 | }
51 | }
52 | }
53 |
54 | return true;
55 | }
56 |
57 | @Override
58 | public T next() {
59 | if (!hasNext()) {
60 | throw new NoSuchElementException();
61 | }
62 |
63 | T toReturn = nextItem;
64 | nextItem = null;
65 | return toReturn;
66 | }
67 |
68 | @Override
69 | public void remove() {
70 | throw new UnsupportedOperationException();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/java/src/collections/RotatingIterator.java:
--------------------------------------------------------------------------------
1 | package collections;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Iterator;
5 | import java.util.NoSuchElementException;
6 |
7 | /**
8 | * Implement a rotating iterator. The iterator accepts an array list of
9 | * iterators, and iterates over them column-wise.
10 | *
11 | * i.e If the following iterators are passed:
12 | *
13 | * iterator_1 => [1] iterator_2 => [2, 3] iterator_3 => [4, 5]
14 | *
15 | * Then the rotating iterator returns the following elements in sequential
16 | * order:
17 | *
18 | * 1, 2, 4, 3, 5.
19 | *
20 | * Methods expected to be implemented:
21 | *
22 | * public class RotatingIterator implements Iterator {
23 | * public RotatingIterator(ArrayList> iterators) {...}
24 | * public boolean hasNext() {...}
25 | * public T next() {...}
26 | * }
27 | */
28 | public class RotatingIterator implements Iterator {
29 |
30 | private final ArrayList> iterators;
31 | private int rotatingIndex;
32 | private T nextItem;
33 |
34 | public RotatingIterator(ArrayList> iterators) {
35 | this.iterators = iterators;
36 | this.rotatingIndex = 0;
37 | }
38 |
39 | @Override
40 | public boolean hasNext() {
41 | if (nextItem != null) {
42 | return true;
43 | }
44 |
45 | int count = 0;
46 | boolean itemFound = false;
47 | while (!itemFound && count < iterators.size()) {
48 | Iterator iterator = iterators.get(rotatingIndex);
49 | if (iterator != null && iterator.hasNext()) {
50 | nextItem = iterator.next();
51 | // we need this because nextItem can possibly be null.
52 | itemFound = true;
53 | }
54 |
55 | rotatingIndex++;
56 | rotatingIndex %= iterators.size();
57 | count++;
58 | }
59 |
60 | return count != iterators.size();
61 | }
62 |
63 | @Override
64 | public T next() {
65 | if (!hasNext()) {
66 | throw new NoSuchElementException();
67 | }
68 |
69 | T toReturn = nextItem;
70 | nextItem = null;
71 | return toReturn;
72 | }
73 |
74 | @Override
75 | public void remove() {
76 | throw new UnsupportedOperationException();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/java/src/common/ArrayUtils.java:
--------------------------------------------------------------------------------
1 | package common;
2 |
3 | import java.util.Comparator;
4 |
5 | /**
6 | * Common methods required for manipulating arrays.
7 | */
8 | public class ArrayUtils {
9 | // Converts an integer array into Integer array.
10 | public static Integer[] autoBox(int[] array) {
11 | if (array == null) {
12 | return null;
13 | }
14 |
15 | Integer[] converted = new Integer[array.length];
16 | for (int index = 0; index < array.length; index++) {
17 | converted[index] = array[index];
18 | }
19 |
20 | return converted;
21 | }
22 |
23 | // Converts a character array into Character array.
24 | public static Character[] autoBox(char[] array) {
25 | if (array == null) {
26 | return null;
27 | }
28 |
29 | Character[] converted = new Character[array.length];
30 | for (int index = 0; index < array.length; index++) {
31 | converted[index] = array[index];
32 | }
33 |
34 | return converted;
35 | }
36 |
37 | // Swaps elements of a character array.
38 | public static void swap(char[] array, int fooIndex, int barIndex) {
39 | char temp = array[fooIndex];
40 | array[fooIndex] = array[barIndex];
41 | array[barIndex] = temp;
42 | }
43 |
44 | // Swaps elements of an integer array.
45 | public static void swap(int[] array, int fooIndex, int barIndex) {
46 | int temp = array[fooIndex];
47 | array[fooIndex] = array[barIndex];
48 | array[barIndex] = temp;
49 | }
50 |
51 | // Swaps elements of a long array.
52 | public static void swap(long[] array, int fooIndex, int barIndex) {
53 | long temp = array[fooIndex];
54 | array[fooIndex] = array[barIndex];
55 | array[barIndex] = temp;
56 | }
57 |
58 | // Swaps elements of an array.
59 | public static