Print all the combinations of elements in a 2D Matrix - java

Print all the combinations of elements in matrix of size m * n.
Sample Example:
1 3 5
2 6 7
Expected Output:
2 , 1
2 , 3
2 , 5
6 , 1
6 , 3
6 , 5
7 , 1
7 , 3
7 , 5
Rules:
- Every combination starts from bottom of matrix and proceeds towards top. It may switch columns though.
- Every combination should have number of elements equal to number of rows.
- A combination can't have an element from the same row present twice.
I never could figure the solution out for general case. I can use 3 loops. But I want to understand the recursive solution. I use Java.

Here's a non-recursive way to solve this problem (it's not all that pretty, but it works for your input). I know you were interested in recursion, but I don't have anything like that for you at the moment. Generally, I avoid recursion due to the size of problems I work with (constant heap space errors due to the size of the recursive stack even when -Xmx60G). Hope this helps.
private static List<int[]> combos;
public static void main(String[] args){
combos = new ArrayList<int[]>();
generate(new int[][]{{1,3,5},{2,6,7}});
for(int[] s : combos){
System.out.println(java.util.Arrays.toString(s));
}
}
private static void generate(int[][] elements) {
int rows = elements.length;
int[] elementsIndex = new int[rows];
int[] elementsTotals = new int[rows];
java.util.Arrays.fill(elementsTotals, elements[0].length);
int curIdx = 0;
int[] c = new int[rows];
while(true){
while(curIdx >= 0){
if(curIdx == rows) {
addCombo(c);
curIdx--;
}
if(elementsIndex[curIdx] == elementsTotals[curIdx]){
elementsIndex[curIdx] = 0;
curIdx--;
} else break;
}
if(curIdx < 0) break;
// toggle order:
// bottom up: elements[rows-curIdx-1][elementsIndex[curIdx]++]
// top down: elements[curIdx][elementsIndex[curIdx]++]
c[curIdx] = elements[rows-curIdx-1][elementsIndex[curIdx]++];
curIdx++;
}
}
private static void addCombo(int[] c){
int[] a = new int[c.length];
System.arraycopy(c, 0, a, 0, c.length);
combos.add(a);
}

A recursive solution would look something like this:
printPermutations(String head, Matrix m)
if m is empty print head and return
else for each item in last row of m
printPermutations(head + item, m - bottom row)
here "head" is all the work we've done so far. In the body of a recursive method, there have to be at least two alternatives, one that outputs a result and ends the recursion, and one that goes deeper. For the deeper alternative, we transfer the selected element to head, remove the bottom row since we can't pick more than one item from any row, and do it again.
Done well, a recursive solution is often simpler and cleaner than using loops. On the other hand, recursion tends to use more memory

Related

Method that fills the gap between an ArrayList in Java

I'm making a method called fillList. The method will require an arrayList in order to work and the output will be void.
What the method is supposed to do is to fill the gaps between the numbers of the List.
Example:
Input:
4 8 5 9
Output:
4 5 6 7 8 7 6 5 6 7 8 9
The code I have so far is this:
public static void fillList(ArrayList<Integer> List) {
for(int i = 0; i < List.size(); i++) {
if(List.get(i) < List.get(i+1) ) {
List.add(List.get(i+1));
} else if(List.get(i) > List.get(i+1)) {
List.add(List.get(i-1));
}
}
}
My idea was to add 1 to the value of the first element if the first element was less than the second element in the List. For example if the first element is 4 then the code would add a 5 to the list and stop once the number added was equal to one less than the second element. And basically do the opposite if the first element was more than the second element.
I don't know how to stop this loop until the numbers that are being added reach the second element of the list. I am not confident about my code as well I'm pretty sure I am making an error I'm not seeing.
Great question, I think you can learn alot by working this one out and really understanding every single line. I have made a litte illutration for you, to visualize the problem better. Hope this can help you. General tips:
variables are always lowercase by convention so write list instead of List
list.add(5) will add the number 5 to the end of your ArrayList. You can use list.add(4, 5) for example to insert the number 5 into the array position 4.
To update the list while iterating over its indices, you can use method List.add(int index, E element), which expects an index and a new element to insert.
While iterating, you need to compare two adjacent elements and insert a new one under the following conditions:
Left element is less than the right one and difference between them is greater than 1. A new element should be equal left + 1.
Left element is greater than the right one, and they differ more than by 1. A new element should be equal left - 1.
Also have a look at the nicely illustrated answer by #yezper. And as a general advice: draw before coding in order to understand the algorithm better.
That's how implementation might look like:
public static void fillList(List<Integer> list) {
for (int i = 0; i < list.size() - 1; i++) {
int left = list.get(i);
int right = list.get(i + 1);
if (left < right && left + 1 != right) {
list.add(i + 1, left + 1);
} else if (left > right && left - 1 != right) {
list.add(i + 1, left - 1);
}
}
}
main()
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>(List.of(4, 8, 5, 9));
fillList(list1);
System.out.println(list1);
}
Output:
[4, 5, 6, 7, 8, 7, 6, 5, 6, 7, 8, 9]

Sorting A Two-Dimensional (2D) Array as a whole without Row/Column Order

I was working on a Two Dimensional Array and I need to sort it in as a whole and not as in One Row/One Column Sort.
Say,
8 7 9 3
-2 0 4 5
1 3 6 -4
It should look like this,
-2 -1 0 1
2 3 4 5
6 7 8 9
I did It.
Took Two-Days to come up with an algorithm. Its not a perfect algorithm and maybe not even well optimized. But It Works.
Explanation
The Idea Is To get The Minimum Value From A Certain Element (say 0,0) To the End Of Array (i.e. a.length, a[0].length) and swapping it with the Certain Element.
Here I have created a Diagram to better understand the logic.
We Do this Till We Reach The Last Element and Voila! We Have a Sorted 2D-Array.
Code [JAVA]
Now, Come's the fun Part from where I lost Two Brain Cells. The Code.
What I have done, Is To Create a function which returns me the minimum value In a Array.
The Function takes two parameter's which is the Starting Element Index i.e.(i,j) from which its supposed to run a loop to end and return the minimum value with its index in a List.
//Helper Method
//row = Row Of Element To Began Loop From
//column = Column Of Element To Began Loop From.
List get_min(int row,int column)
{
List<Integer> l = new ArrayList<Integer>(); // List To Return with the output.
int mn=a[row][column], mni=0,mnj=0;
//mni= The Row Of Minimum Element
// mnj = The Column Of Minimum Element
for(int i=row;i<a.length;i++)
{
for(int j=column;j<a[0].length;j++)
{
if(mn>a[i][j])
{
mni = i;
mnj = j;
mn=a[i][j];
}
}
column=0; // This needs to be zero, just so the next time Row Updates The Loop doesn't began from the 2nd Element But 0.
}
l.add(mn); l.add(mni); l.add(mnj);
return l;
}
Now We Have A List With Three Values, The Minimum Element, The Minimum Element Row, The Minimum Element Column. We Can Now Build A Simple, Swap Function with the Use of Helper Method Above.
void sort_array()
{
for(int i=0; i<a.length;i++)
{
for(int j=0;j<a[0].length;j++)
{
List<Integer> l = get_min(i, j); // List with Minimum Value As In Step 1,Step 2, Step 3
if(a[i][j]>l.get(0)) // Check To Prevent Last Value Replacing The First Element
{
//Simple Swap
int t = a[i][j];
a[i][j] = l.get(0);
a[l.get(1)][l.get(2)] = t;
}
}
}
}
Voila Now You Have An Sorted 2D-Array. Enjoy with the data.

time complexity for array search

i am writing the function to check if the given value is included in the matrix in . This matrix has the following properties:
•Integers in each row are sorted in ascending from left to right.
•Integers in each column are sorted in ascending from top to bottom
public static boolean searchMatrix(int target, int[][] matrix)
{
for(int i = 0;i <= matrix[0].length;i++)
{
for (int j=i; j<matrix.length;j++)
{
if(target == matrix[i][j])
return true;
}
}
return false;
}
i want to know weather this program has time complexity of O(N).
if not what changes should i make to get into O(N).
I think the search can be done in linear time. Consider the following 4×4 matrix as a visual:
1 2 4 6
2 3 5 7 ascending from left to right
3 4 6 8 and from top to bottom
4 5 6 9
If we were searching for the value 5 we could begin in the upper left, and then walk to the right until we have either found the value, or encountered a number which is greater than the target of 5. In this case, we hit 6. Then, we can rollback to 4, and advance down to a higher row. It is guaranteed that every previous value in the first row is less than the target and that every value in the next row from that column onwards is greater than the value on the first row.
This is a roughly linear approach. A good analogy would be walking around the perimeter of a mountain, looking for a certain elevation. If at each spot we either don't find the height we want, or find only points too high, we keep walking.
The way you have it written (brute force computation) has a worst case time complexity of O(N^2). Since you say that the arrays are sorted, you can instead implement binary search which will have a worst case time complexity of N(2*log(N)).
Assuming a n x m matrix, your algorithm is O(n * m), because it (potentially) iterates all rows and columns (ie all elements).
However, there exists an algorithm that is O(log(m + n)).
Because this is for an on-line coding interview (I am psychic), I will give you hints only:
Given elements at coordinate (x, y), what can know about where the target might be?
What could you do if you treated x and y separately?
you say the matrix is sorted ,may you can use binary search to find the target . and use two individual one layer loop , firstly search row ,then column.it's o(N/2).
As stated your algorithm is O(N*M) or O(N^2) for a square matrix.
You can do it with a single loop:
Basically starting from the top right you check the cell if the number is too big move left if the number is too small move down. If you fall off the edge on either side the number's not there.
boolean searchMatrix(int target, int[][] mat)
{
int i = 0, j = mat[0].length;
while (i < mat.length && j >= 0)
{
if (mat[i][j] == target)
{
return true;
}
else if (mat[i][j] < target)
{
i++;
}
else
{
j--;
}
}
return false;
}

Java how to return a function that returns a 2d array right angle pattern

Consider a set of number grids like:
1 1 2 1 2 3
2 2 2 2 3
3 3 3
In other words, a square grid where the number in each position follows a right-angle pattern. How do I write a function that creates, fills in, and returns such a 2d array?
( Also, I'm wondering if Math.max(a, b) would be useful for filling in the grid. I'm wondering if it could return which value is greater between two inputs a and b.)
I already have a function set up, but I don't know where to start:
int[][] cornerPattern(int squareSize) {
}
Hints would be fine
Most of the java programs can easily be solved or atleast initiated by finding a pattern.
So whats the pattern here?
The pattern is that the relation between array index and the element at that place. Every index which has 0 in it has 1 so arr[0][0] is 1.See the pattern there? Every index which has [1] in it has 2. So arr[0][1], arr[1][0] and arr[1][1] are 2 and same is the condition with 3. The size of the array is also defined in the same way. 3, will be [3][3] matrix.
Hope that helps. :)
You are looking for something like this
int m =//input;
int[][] arr = new int[m][m];
for(int i=0;i<m;i++){
for(int j=0;j<m;j++){
if(i>=j)
arr[i][j]=i;
else
arr[i][j]=j;
System.out.print(arr[i][j]);
}
System.out.println();
}

How to get partition of quicksort to produce the correct and expected output?

This concerns "a software algorithm" from https://stackoverflow.com/help/on-topic, in this case the quicksort sorting algorithm
This is a practice coding question(non competition) from https://www.hackerrank.com/challenges/quicksort1
Basically you're supposed to take in a list, say
4 5 3 7 2
and partition around the first element, in this case 4. The expected output is
3 2 4 5 7
However the output I am getting is
2 3 4 7 5
Here is my code for doing the partitioning(based off the learning friendly version from https://courses.cs.washington.edu/courses/cse373/13wi/lectures/02-27/20-sorting3-merge-quick.pdf slide 16)
static void partition(int[] ar) {
int toPartitionAround = ar[0];
swap(ar, 0, ar.length - 1);
int index = partition(ar, 0, ar.length - 2, toPartitionAround);
swap(ar, index, ar.length - 1);
printArray(ar);
}
static int partition(int[] ar, int left, int right, int toAround) {
while(left <= right) {
while(ar[left] < toAround) {
left ++;
}
while(ar[right] > toAround) {
right --;
}
if(left <= right) {
swap(ar, left, right);
left ++;
right --;
}
}
return left;
}
static void swap(int[] arrayNums, int index1, int index2) {
int temp = arrayNums[index1];
arrayNums[index1] = arrayNums[index2];
arrayNums[index2] = temp;
}
Is there a modification I can make to this to match the expected output? Am I technically still getting a possible correct output because my output does follow the property elements to the left of the pivot are less than the pivot and elements to the right of the pivot are greater than the pivot?
What I do is assign the pivot, move it to the back of the array and then partition the rest of the array around the pivot (from index of 0 to length - 2). With this input, one swap happened when going through the array(3 and the 5). Then when I get index from the result of the partition, I swap the pivot with that result, meaning I swap 4 and 5.
Do I follow a similar process to get the expected output? I can't see what to replace.
After reading #greybeard's and #Smac89's comments, I realized I needed a stable form of quicksort, stable as in "preserving the original order of the input set, where the comparison algorithm does not distinguish between two or more items"(https://softwareengineering.stackexchange.com/questions/247440/what-does-it-mean-for-a-sorting-algorithm-to-be-stable)
To me a stable sort doesn't really make sense for this run because the comparison algorithm does distinguish between 3 and 2, but oh well. Can someone clarify this?
The solution I came up with to maintain relative was creating two ArrayLists, one for holding values less than or equal to the pivot and one for holding values greater than the pivot. This way relative positioning is preserved.(2 will come after the 3, just like in the original list). Then I move the values from the two ArrayLists along with the pivot back into the original pivot.
Here is my solution in code if anyone is having troubles with this
static void partition(int[] ar) {
List<Integer> smallerValues = new ArrayList<Integer>();
List<Integer> biggerValues = new ArrayList<Integer>();
int toPartitionAround = ar[0];
for(int c=1;c<ar.length;c++) {
if(ar[c] <= toPartitionAround) {
smallerValues.add(ar[c]);
} else {
biggerValues.add(ar[c]);
}
}
for(int c=0;c<smallerValues.size();c++) {
ar[c] = smallerValues.get(c);
}
ar[smallerValues.size()] = toPartitionAround;
for(int m=0;m<biggerValues.size();m++) {
ar[m + smallerValues.size() + 1] = biggerValues.get(m);
}
printArray(ar);
}
That's a little confusing one isn't it. All I did to solve that question was create 2 separate lists, one to store elements lower than pivot and another to store elements higher than the pivot. Then, you just print out the values. This is the way preserve the order of elements and you do an "in-place" sorting. But it consumes memory as well.

Categories