diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 92cd1eb..dac362a 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,9 +4,9 @@
-
+
+
-
@@ -81,21 +81,22 @@
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"git-widget-placeholder": "back__tracking",
"onboarding.tips.debug.path": "/Users/subhamsantra/Projects/Interview/TheAlgorithm/src/main/java/com/subham/ta/Main.java",
- "settings.editor.selected.configurable": "preferences.lookFeel"
+ "settings.editor.selected.configurable": "editor.preferences.completion"
}
}]]>
+
-
-
-
+
+
+
-
+
@@ -103,12 +104,12 @@
-
-
+
+
-
+
@@ -116,12 +117,12 @@
-
-
+
+
-
+
@@ -129,12 +130,12 @@
-
-
+
+
-
+
@@ -142,12 +143,12 @@
-
-
+
+
-
+
@@ -157,11 +158,11 @@
+
+
+
+
-
-
-
-
@@ -374,7 +375,55 @@
1724742612046
-
+
+
+ 1724869859287
+
+
+
+ 1724869859287
+
+
+
+ 1724869912287
+
+
+
+ 1724869912287
+
+
+
+ 1724954143566
+
+
+
+ 1724954143566
+
+
+
+ 1725033464461
+
+
+
+ 1725033464461
+
+
+
+ 1725044292132
+
+
+
+ 1725044292132
+
+
+
+ 1725088358813
+
+
+
+ 1725088358813
+
+
@@ -403,7 +452,12 @@
-
+
+
+
+
+
+
diff --git a/src/main/java/com/thealgorithm/graph/CollectCoinsInATree.java b/src/main/java/com/thealgorithm/graph/CollectCoinsInATree.java
new file mode 100644
index 0000000..7eafe6d
--- /dev/null
+++ b/src/main/java/com/thealgorithm/graph/CollectCoinsInATree.java
@@ -0,0 +1,20 @@
+package com.thealgorithm.graph;
+
+/**
+ * @author: Subham Santra
+ */
+public class CollectCoinsInATree {
+
+ public int collectTheCoins(int[] coins, int[][] edges) {
+ return 0;
+ }
+
+ public static void main(String[] args) {
+
+ System.out.println(
+ new CollectCoinsInATree()
+ .collectTheCoins(
+ new int[] {1, 0, 0, 0, 0, 1},
+ new int[][] {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}}));
+ }
+}
diff --git a/src/main/java/com/thealgorithm/graph/Edge.java b/src/main/java/com/thealgorithm/graph/Edge.java
index 0bdd265..d0bf120 100644
--- a/src/main/java/com/thealgorithm/graph/Edge.java
+++ b/src/main/java/com/thealgorithm/graph/Edge.java
@@ -16,6 +16,10 @@ public static Edge createSimpleEdgeUnWeighted(V v1, V v2) {
return new Edge<>(Vertex.create(v1), Vertex.create(v2), 0D);
}
+ public static Edge createEdge(V v1, V v2, double weight) {
+ return new Edge<>(Vertex.create(v1), Vertex.create(v2), weight);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -29,4 +33,9 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(getVertex1(), getVertex2(), getWeight());
}
+
+ @Override
+ public String toString() {
+ return "<" + vertex1.getKey() + "--" + vertex2.getKey() + "|" + weight + '>';
+ }
}
diff --git a/src/main/java/com/thealgorithm/graph/Graph.java b/src/main/java/com/thealgorithm/graph/Graph.java
index 51f39ed..abad3c4 100644
--- a/src/main/java/com/thealgorithm/graph/Graph.java
+++ b/src/main/java/com/thealgorithm/graph/Graph.java
@@ -32,4 +32,10 @@ public void addEdge(Edge edge) {
}
}
}
+
+ void clear() {
+ vertexSet.clear();
+ edgeSet.clear();
+ isDirected = false;
+ }
}
diff --git a/src/main/java/com/thealgorithm/graph/MostStonesRemovedSameRowCol.java b/src/main/java/com/thealgorithm/graph/MostStonesRemovedSameRowCol.java
new file mode 100644
index 0000000..284ada7
--- /dev/null
+++ b/src/main/java/com/thealgorithm/graph/MostStonesRemovedSameRowCol.java
@@ -0,0 +1,136 @@
+package com.thealgorithm.graph;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * @author: Subham Santra
+ */
+public class MostStonesRemovedSameRowCol {
+
+ static class Solution {
+ static class Vertex {
+ int row;
+ int col;
+
+ public Vertex(int row, int col) {
+ this.row = row;
+ this.col = col;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Vertex vertex)) return false;
+ return row == vertex.row && col == vertex.col;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(row, col);
+ }
+
+ @Override
+ public String toString() {
+ return "{" + row + ", " + col + '}';
+ }
+ }
+
+ /**
+ * The intuition is -- As all the vertices will be connected - we will use DFS to find out no of
+ * connected components
+ *
+ * @param stones
+ * @return
+ */
+ public int removeStones(int[][] stones) {
+ Map> graph = new HashMap<>();
+ Map> rowMap = new HashMap<>();
+ Map> colMap = new HashMap<>();
+
+ for (int[] stone : stones) {
+ Vertex vertex = new Vertex(stone[0], stone[1]);
+ if (rowMap.containsKey(vertex.row)) {
+ for (Vertex sameRowVertex : rowMap.get(vertex.row)) {
+ graph.putIfAbsent(vertex, new HashSet<>());
+ graph.get(vertex).add(sameRowVertex);
+
+ graph.putIfAbsent(sameRowVertex, new HashSet<>());
+ graph.get(sameRowVertex).add(vertex);
+ }
+ }
+ if (colMap.containsKey(vertex.col)) {
+ for (Vertex sameColVertex : colMap.get(vertex.col)) {
+ graph.putIfAbsent(vertex, new HashSet<>());
+ graph.get(vertex).add(sameColVertex);
+
+ graph.putIfAbsent(sameColVertex, new HashSet<>());
+ graph.get(sameColVertex).add(vertex);
+ }
+ }
+
+ rowMap.putIfAbsent(vertex.row, new HashSet<>());
+ colMap.putIfAbsent(vertex.col, new HashSet<>());
+
+ rowMap.get(vertex.row).add(vertex);
+ colMap.get(vertex.col).add(vertex);
+ }
+
+ Set removedVertices = new HashSet<>();
+ int connectedComponents = 0;
+ for (int[] stone : stones) {
+ Vertex vertex = new Vertex(stone[0], stone[1]);
+ if (!removedVertices.contains(vertex)) {
+ ++connectedComponents;
+ DFS(graph, removedVertices, vertex);
+ }
+ }
+
+ return stones.length - connectedComponents;
+ }
+
+ /**
+ * This method will check each vertex and remove it. This will continue to remove all the
+ * connected vertices
+ *
+ * @param graph
+ * @param removedVertices
+ * @param vertex
+ */
+ private void DFS(Map> graph, Set removedVertices, Vertex vertex) {
+ if (removedVertices.contains(vertex)) {
+ return;
+ }
+
+ if (!graph.containsKey(vertex)) {
+ return;
+ }
+
+ removedVertices.add(vertex);
+ for (Vertex nextVertex : graph.get(vertex)) {
+ DFS(graph, removedVertices, nextVertex);
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ System.out.println(
+ new Solution().removeStones(new int[][] {{0, 0}, {0, 1}, {1, 0}, {1, 2}, {2, 1}, {2, 2}}));
+
+ System.out.println(new Solution().removeStones(new int[][] {{0, 1}, {1, 0}, {1, 1}}));
+
+ System.out.println(
+ new Solution().removeStones(new int[][] {{0, 0}, {0, 2}, {1, 1}, {2, 0}, {2, 2}}));
+
+ System.out.println(
+ new Solution()
+ .removeStones(
+ new int[][] {
+ {0, 0}, {0, 1}, {1, 0}, {1, 1}, {2, 1}, {2, 2}, {3, 2}, {3, 3}, {3, 4}, {4, 3},
+ {4, 4}
+ }));
+ }
+}
diff --git a/src/main/java/com/thealgorithm/graph/PrimsMST.java b/src/main/java/com/thealgorithm/graph/PrimsMST.java
deleted file mode 100644
index 7f79a77..0000000
--- a/src/main/java/com/thealgorithm/graph/PrimsMST.java
+++ /dev/null
@@ -1,137 +0,0 @@
-// package com.subham.ta.graph;
-//
-// import static java.util.Collections.swap;
-//
-// import java.util.ArrayList;
-// import java.util.HashMap;
-// import java.util.List;
-// import java.util.Map;
-// import java.util.Set;
-//
-// public class PrimsMST {
-// private static final int INF = Integer.MAX_VALUE;
-//
-// static class Graph {
-// Map> edges;
-// Set nodes;
-//
-// public Graph() {
-// this.edges = new HashMap<>();
-// }
-//
-// void addEdge(int u, int v, int w) {
-// edges.putIfAbsent(u, new HashMap<>());
-// edges.get(u).putIfAbsent(v, w);
-// nodes.add(u);
-// nodes.add(v);
-// }
-//
-// int noOfNodes() {
-// return nodes.size();
-// }
-//
-// Set getAllNodes() {
-// return nodes;
-// }
-// }
-//
-// static class BinaryMinHeap {
-// int size;
-// List tree;
-// Map valToIndex;
-// Map valToWeight;
-//
-// BinaryMinHeap(int size) {
-// this.size = size;
-// this.tree = new ArrayList<>();
-// this.valToIndex = new HashMap<>();
-// this.valToWeight = new HashMap<>();
-// }
-//
-// public BinaryMinHeap(Graph graph) {
-// this(graph.noOfNodes());
-// for (int node : graph.getAllNodes()) {
-// this.addEntry(node, INF);
-// heapify(valToIndex.get(node));
-// }
-// }
-//
-// private void heapify(int index) {
-// if (index <= 0 || index >= this.tree.size()) {
-// return;
-// }
-// int parent = (index - 1) / 2;
-// if (valToWeight.get(tree.get(parent)) > valToWeight.get(tree.get(index))) {
-// swap(tree, index, parent);
-// }
-// heapify(parent);
-// }
-//
-// private void addEntry(int node, int val) {
-// this.tree.add(node);
-// this.valToWeight.put(node, val);
-// this.valToIndex.put(node, this.tree.size() - 1);
-// }
-//
-// public void decrease(int node, int newVal) {
-// int index = valToIndex.get(node);
-// valToWeight.put(node, newVal);
-// heapify(index);
-// }
-//
-// public int[] getNode(int index) {
-// return new int[] {tree.get(index), valToWeight.get(tree.get(index))};
-// }
-//
-// public int[] extractMin() {
-// int[] topNode = getNode(0);
-// int[] lastNode = getNode(tree.size() - 1);
-//
-// // re-balance the heap
-//
-// int currentIndex = 0;
-//
-// swap(tree, tree.size() - 1, 0);
-// valToIndex.put(lastNode[0], 0);
-//
-// tree.removeLast();
-// valToIndex.remove(topNode[0]);
-// valToWeight.remove(topNode[0]);
-//
-// while (true) {
-// int leftChildIndex = (currentIndex * 2) + 1;
-// int rightChildIndex = (currentIndex * 2) + 2;
-//
-// int[] leftNode = getNode(leftChildIndex);
-// int[] rightNode = getNode(rightChildIndex);
-//
-// if (leftNode[1] < rightNode[1]) {
-// valToIndex.put(leftNode[0], leftChildIndex);
-// valToIndex.put()
-// swap(tree, currentIndex, leftChildIndex);
-// }
-// }
-//
-// return topNode;
-// }
-// }
-//
-// public static void main(String[] args) {
-// Graph graph = new Graph();
-//
-// graph.addEdge(1, 2, 1);
-// graph.addEdge(1, 3, 3);
-// graph.addEdge(1, 4, 1);
-// graph.addEdge(3, 4, 2);
-// graph.addEdge(4, 5, 10);
-// graph.addEdge(2, 5, 2);
-//
-// System.out.println(findMST(graph));
-// }
-//
-// private static List findMST(Graph graph) {
-// // build binary-min-heap from graph
-//
-// return null;
-// }
-// }
diff --git a/src/main/java/com/thealgorithm/graph/PrimsMinimumSpanningTree.java b/src/main/java/com/thealgorithm/graph/PrimsMinimumSpanningTree.java
new file mode 100644
index 0000000..8673948
--- /dev/null
+++ b/src/main/java/com/thealgorithm/graph/PrimsMinimumSpanningTree.java
@@ -0,0 +1,44 @@
+package com.thealgorithm.graph;
+
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.PriorityQueue;
+import java.util.Set;
+
+/**
+ * @author: Subham Santra
+ */
+public class PrimsMinimumSpanningTree {
+
+ public Set> findMST(final Graph graph) {
+ Set> visited = new HashSet<>();
+ PriorityQueue> edgePQ =
+ new PriorityQueue<>(Comparator.comparingDouble(Edge::getWeight));
+ Set> minimumSpanningTree = new HashSet<>();
+
+ edgePQ.addAll(graph.getEdgeSet());
+
+ while ((!edgePQ.isEmpty()) && (visited.size() < graph.getVertexSet().size())) {
+ Edge currentMinimumEdge = edgePQ.poll();
+ visited.add(currentMinimumEdge.getVertex1());
+ visited.add(currentMinimumEdge.getVertex2());
+ minimumSpanningTree.add(currentMinimumEdge);
+ }
+
+ return minimumSpanningTree;
+ }
+
+ // Test code
+ public static void main(String[] args) {
+ Graph graph = new Graph<>(false);
+
+ graph.addEdge(Edge.createEdge(1, 2, 4));
+ graph.addEdge(Edge.createEdge(1, 3, 1));
+ graph.addEdge(Edge.createEdge(1, 5, 3));
+ graph.addEdge(Edge.createEdge(5, 4, 1));
+ graph.addEdge(Edge.createEdge(5, 3, 1));
+ graph.addEdge(Edge.createEdge(2, 4, 2));
+
+ System.out.println(new PrimsMinimumSpanningTree().findMST(graph));
+ }
+}
diff --git a/src/main/java/com/thealgorithm/graph/ShortestCycleInGraph.java b/src/main/java/com/thealgorithm/graph/ShortestCycleInGraph.java
new file mode 100644
index 0000000..30809d4
--- /dev/null
+++ b/src/main/java/com/thealgorithm/graph/ShortestCycleInGraph.java
@@ -0,0 +1,106 @@
+package com.thealgorithm.graph;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+
+/**
+ * @author: Subham Santra
+ */
+public class ShortestCycleInGraph {
+ public int findShortestCycle(int n, int[][] edges) {
+
+ // Build the Graph DS
+ Map> graph = new HashMap<>();
+ for (int[] edge : edges) {
+ graph.putIfAbsent(edge[0], new ArrayList<>());
+ graph.putIfAbsent(edge[1], new ArrayList<>());
+
+ graph.get(edge[0]).add(edge[1]);
+ graph.get(edge[1]).add(edge[0]);
+ }
+
+ // System.out.println(graph);
+
+ // Will do BFS
+ // But we need to know for each node - the shortest cycle that node is part of.
+ return BFS(graph, n);
+ }
+
+ int BFS(Map> graph, int n) {
+ int[] shortestCycleCount = new int[n];
+ Arrays.fill(shortestCycleCount, Integer.MAX_VALUE);
+
+ // Will perform breadth first search on all nodes
+ for (int node = 0; node < n; ++node) {
+ int[] time = new int[n];
+ Queue queue = new ArrayDeque<>();
+ queue.add(new int[] {node, 0, -1});
+
+ while (!queue.isEmpty()) {
+ int[] _node = queue.poll();
+ int currentNode = _node[0];
+ int visitingTime = _node[1];
+ int parentNode = _node[2];
+
+ // the current node is already visited
+ // that means this is a cycle with 'node'
+ if (time[currentNode] > 0) {
+ shortestCycleCount[node] =
+ Math.min(shortestCycleCount[node], time[currentNode] + visitingTime);
+ continue;
+ }
+
+ // calculate current node's visiting time.
+ // if not first time, then always keep the lowest visiting time from 'node' to 'currentNode'
+ time[currentNode] =
+ (time[currentNode] == 0) ? visitingTime : Math.min(time[currentNode], visitingTime);
+
+ for (int child : graph.getOrDefault(currentNode, Collections.emptyList())) {
+ if (child == parentNode) {
+ continue;
+ }
+
+ queue.add(new int[] {child, visitingTime + 1, currentNode});
+ }
+ }
+ }
+ // System.out.println(Arrays.toString(shortestCycleCount));
+ return Arrays.stream(shortestCycleCount).filter(i -> i != Integer.MAX_VALUE).min().orElse(-1);
+ }
+
+ public static void main(String[] args) {
+ System.out.println(
+ new ShortestCycleInGraph()
+ .findShortestCycle(
+ 7, new int[][] {{0, 1}, {1, 2}, {2, 0}, {3, 4}, {4, 5}, {5, 6}, {6, 3}}));
+
+ System.out.println(
+ new ShortestCycleInGraph()
+ .findShortestCycle(
+ 9,
+ new int[][] {
+ {0, 1}, {1, 2}, {2, 3}, {0, 3}, {3, 4}, {4, 5}, {5, 6}, {7, 8}, {8, 0}
+ }));
+
+ System.out.println(
+ new ShortestCycleInGraph().findShortestCycle(3, new int[][] {{0, 1}, {1, 2}}));
+
+ System.out.println(
+ new ShortestCycleInGraph()
+ .findShortestCycle(
+ 6, new int[][] {{4, 1}, {5, 1}, {3, 2}, {5, 0}, {4, 0}, {3, 0}, {2, 1}}));
+
+ // Exception test case;
+ // ans: 4
+ System.out.println(
+ new ShortestCycleInGraph()
+ .findShortestCycle(
+ 6, new int[][] {{4, 2}, {5, 1}, {5, 0}, {0, 3}, {5, 2}, {1, 4}, {1, 3}, {3, 4}}));
+ }
+}
diff --git a/src/main/java/com/thealgorithm/lld/ParkingLotLLD.java b/src/main/java/com/thealgorithm/lld/ParkingLotLLD.java
new file mode 100644
index 0000000..28204cd
--- /dev/null
+++ b/src/main/java/com/thealgorithm/lld/ParkingLotLLD.java
@@ -0,0 +1,113 @@
+package com.thealgorithm.lld;
+
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.util.List;
+import lombok.Data;
+
+/**
+ * @author: Subham Santra
+ */
+@Data
+abstract class Vehicle {
+ String vehicleNumber;
+ String registration;
+ String owner;
+}
+
+class Bike extends Vehicle {}
+
+class Car extends Vehicle {}
+
+class Truck extends Vehicle {}
+
+@Data
+abstract class ParkingSpot {
+ int level;
+ int id;
+ boolean isOccupied;
+ Vehicle occupiedVehicle;
+ Timestamp occupiedAt;
+
+ abstract boolean canOccupy(Vehicle vehicle);
+
+ public boolean occupy(Vehicle vehicle) {
+ if (canOccupy(vehicle)) {
+ isOccupied = true;
+ occupiedVehicle = vehicle;
+ occupiedAt = Timestamp.from(Instant.now());
+ return true;
+ }
+ return false;
+ }
+}
+
+class BikeParkingSpot extends ParkingSpot {
+ @Override
+ boolean canOccupy(Vehicle vehicle) {
+ return (vehicle instanceof Bike) && !isOccupied();
+ }
+}
+
+class CarParkingSpot extends ParkingSpot {
+ @Override
+ boolean canOccupy(Vehicle vehicle) {
+ return (vehicle instanceof Car) && !isOccupied();
+ }
+}
+
+class TruckParkingSpot extends ParkingSpot {
+ @Override
+ boolean canOccupy(Vehicle vehicle) {
+ return (vehicle instanceof Car) && !isOccupied();
+ }
+}
+
+class ParkingSpotNotEmptyException extends Exception {
+ public ParkingSpotNotEmptyException(int parkingSpotId) {
+ super(Integer.toString(parkingSpotId));
+ }
+}
+
+@Data
+class Level {
+ int level;
+ List parkingSpots;
+
+ void addMore(ParkingSpot parkingSpot) {
+ parkingSpot.setLevel(level);
+ this.parkingSpots.add(parkingSpot);
+ }
+
+ void remove(int parkingSpotId) throws ParkingSpotNotEmptyException {
+ for (ParkingSpot parkingSpot : parkingSpots) {
+ if (parkingSpot.getId() == parkingSpotId) {
+ if (parkingSpot.isOccupied()) {
+ throw new ParkingSpotNotEmptyException(parkingSpotId);
+ } else {
+ parkingSpots.remove(parkingSpot);
+ }
+ }
+ }
+ }
+
+ ParkingSpot parkThis(Vehicle vehicle) {
+ for (ParkingSpot parkingSpot : parkingSpots) {
+ if (parkingSpot.occupy(vehicle)) {
+ return parkingSpot;
+ }
+ }
+ return null;
+ }
+}
+
+@Data
+class ParkingLot {
+ List parkingLevels;
+
+ void park(final Vehicle vehicle) {
+
+ }
+}
+
+public class ParkingLotLLD {}
diff --git a/src/main/java/com/thealgorithm/stacks/LargestSubMatrixWithRearrangements.java b/src/main/java/com/thealgorithm/stacks/LargestSubMatrixWithRearrangements.java
new file mode 100644
index 0000000..75c33d0
--- /dev/null
+++ b/src/main/java/com/thealgorithm/stacks/LargestSubMatrixWithRearrangements.java
@@ -0,0 +1,66 @@
+package com.thealgorithm.stacks;
+
+import java.util.Arrays;
+import java.util.Stack;
+
+/**
+ * @author: Subham Santra
+ */
+public class LargestSubMatrixWithRearrangements {
+ public int largestSubmatrix(int[][] matrix) {
+ int m = matrix.length;
+ int n = matrix[0].length;
+ int[][] prefixSum = new int[m][n];
+
+ System.arraycopy(matrix[0], 0, prefixSum[0], 0, n);
+
+ for (int i = 1; i < m; ++i) {
+ for (int j = 0; j < n; ++j) {
+ prefixSum[i][j] = matrix[i][j] == 0 ? 0 : prefixSum[i - 1][j] + matrix[i][j];
+ }
+ }
+
+ int result = 0;
+
+ for (int i = 0; i < m; ++i) { // O(R)
+ // O(ClogC) + O(C) = O(ClogC)
+ Arrays.sort(prefixSum[i]); // O(ClogC)
+ result = Math.max(result, largestHistogram(prefixSum[i])); // O(C)
+ }
+
+ // Overall TC : O(RClogC) -> O(mn(log n))
+ return result;
+ }
+
+ private int largestHistogram(int[] arr) {
+ Stack stack = new Stack<>();
+ int[] temp = new int[arr.length];
+ for (int i = 0; i < arr.length; ++i) {
+ int backIndex = i;
+ while (!stack.isEmpty() && (stack.peek()[0] > arr[i])) {
+ backIndex = stack.pop()[1];
+ }
+ temp[i] = arr[i] * (backIndex - i + 1);
+ stack.push(new int[] {arr[i], backIndex, i});
+ }
+ while (!stack.isEmpty()) {
+ temp[stack.peek()[2]] = stack.peek()[0] * (arr.length - stack.peek()[2]);
+ stack.pop();
+ }
+ return Arrays.stream(temp).max().orElse(0);
+ }
+
+ public static void main(String[] args) {
+ System.out.println(
+ new LargestSubMatrixWithRearrangements()
+ .largestSubmatrix(new int[][] {{1, 1, 0}, {1, 0, 1}}));
+
+ System.out.println(
+ new LargestSubMatrixWithRearrangements()
+ .largestSubmatrix(new int[][] {{0, 0, 1}, {1, 1, 1}, {1, 0, 1}}));
+
+ System.out.println(
+ new LargestSubMatrixWithRearrangements()
+ .largestSubmatrix(new int[][] {{1, 0, 1, 1, 0, 1}}));
+ }
+}