diff --git a/CrossTrainingIII.java b/CrossTrainingIII.java
new file mode 100644
index 0000000..41867e5
--- /dev/null
+++ b/CrossTrainingIII.java
@@ -0,0 +1,63 @@
+import java.util.*;
+
+public class CrossTrainingIII {
+ /**
+ * Common Numbers Of Two Arrays I(Array version)
+ *
+ * Find all numbers that appear in both of the two unsorted arrays, return the
+ * common numbers in increasing order.
+ */
+ public List common(int[] a, int[] b) {
+ Arrays.sort(a);
+ Arrays.sort(b);
+ List result = new ArrayList<>();
+
+ int i = 0;
+ int j = 0;
+
+ while (i < a.length && j < b.length) {
+ if (a[i] == b[j]) {
+ result.add(a[i]);
+ i++;
+ j++;
+ } else if (a[i] > b[j]) {
+ j++;
+ } else {
+ i++;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Largest Rectangle In Histogram
+ *
+ * Given a non-negative integer array representing the heights of a list of
+ * adjacent bars. Suppose each bar has a width of 1. Find the largest
+ * rectangular area that can be formed in the histogram.
+ */
+ public int largest(int[] array) {
+ int result = 0;
+ Deque stack = new ArrayDeque<>();
+ for (int i = 0; i < array.length; i++) {
+ if (stack.isEmpty()) {
+ stack.offerLast(i);
+ } else if (array[stack.peekLast()] > array[i]) {
+ int prev = 0;
+ int prevMax = 0;
+ while (!stack.isEmpty() && array[stack.peekLast()] > array[i]) {
+ prev = stack.pollLast();
+ prevMax = array[prev];
+ }
+ prev = stack.isEmpty() ? -1 : prev;
+
+ result = Math.max((i - 1 - prev) * prevMax, result);
+ } else {
+ stack.offerLast(i);
+ }
+ }
+ result = Math.max((array.length - stack.peekFirst()) * array[stack.peekFirst()], result);
+
+ return result;
+ }
+}
diff --git a/DFSII.java b/DFSII.java
index 4097979..9efd46c 100644
--- a/DFSII.java
+++ b/DFSII.java
@@ -351,6 +351,9 @@ public int[] keepDistance(int k) {
}
private boolean keepDistance(int[] result, int n) {
+ if (n == 0) {
+ return true;
+ }
for (int i = 0; i + n + 1 < result.length; i++) {
if (result[i] == 0 && result[i + n + 1] == 0) {
result[i] = n;