Space complexity of a temp array that is outside a loop - java

I did come across a famous interview question, in which we are given a 2D array and we need to rotate the array by 90 degrees and while there are many ways to solve it, I decided to make use of an effective approach in which we do something like this.
/*
* clockwise rotate
* first reverse up to down, then swap the symmetry
* 1 2 3 7 8 9 7 4 1
* 4 5 6 => 4 5 6 => 8 5 2
* 7 8 9 1 2 3 9 6 3
*/
My code for above approach is:
public void rotate(int[][] matrix) {
int s = 0, e = matrix.length - 1;
while(s < e){
int[] temp = matrix[s];
matrix[s] = matrix[e];
matrix[e] = temp;
s++; e--;
}
for(int i = 0; i < matrix.length; i++){
for(int j = i+1; j < matrix[i].length; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
}
My main concern here is that the array that i'm using inside the first while loop might make the space complexity O(n). What if I simply do this:
int[] temp;
while( s < e ){
temp = matrix[s];
}
Would now be the space complexity O(1) or will it remain the same?

Your only space outside of the matrix being rotated is a single element and a pointer to a row, each of which is O(1). That the pointer points to something of O(N) space is irrelevant, as it is part of the input.
Note that you can do the rotation in about 1/2 the time: instead of reflecting the whole matrix two ways, moving each element twice, you can instead rotate each set of 4 elements where A replace B, B replaces C, C replaces D, and D replaces A.

Related

Adding each column in a 2D array which become values of the last row

I'm trying to add all of the values for each column in a 2D array and these sums become values that overwrite the last row of the array
for example:
4 5 6 7 8
1 2 3 4 5
0 0 0 0 0 //this row will be replaced by the sum of each column
4 5 6 7 8
1 2 3 4 5
5 7 9 11 13
public static void fillTotals(int[][] scores)
{
int count = 0;
for (int r = 0; r < scores.length - 1; r++)
{
scores[r][0] += count;
scores[scores.length - 1][scores[0].length - 1] = count;
}
}
I thought I could keep the columns the same and add it down with the changing rows but it isn't rewriting the last row. Also I don't know how to change the values at the bottom
You need to iterate once over all rows and columns, actually iterate over all rows, for every column. If you assume that the number of columns is the same for every row, then you can use scores[0].length as a fixed value.
public static void fillTotals(int[][] scores) {
for (int c=0; c < scores[0].length; ++c) {
int sum = 0;
for (int r=0; r < scores.length - 1; ++r) {
sum += scores[r][c];
}
scores[scores.length - 1][c] = sum;
}
}
This assumes that the final row of the 2D array is not part of the sum and is available to be overwritten with the sum of all preceding values, for each column.
Well, the reason that nothing is being updated is that you never change count, so you just end up adding 0 to everything. I think what you want instead of:
scores[r][0] += count;
is:
count += scores[r][0];
That way count will contain the summation of every element in the first column.
To be clear, scores[r][0] += count; is the same as scores[r][0] = scores[r][0] + count;, whereas I think you probably want count = scores[r][0] + count;
That being said, Im still pretty sure this code isnt actually going to work (sorry), since you only ever actually sum values from the first column. However, for the sake of not just doing way may be a school assignment for you, Im just going to leave it there. If you're still stuck let me know, and I'll try to help!

Why are there two for-loops in this method for sorting cards in an array?

Write a Cards class and a sortCards method such that it sorts a cards array argument such that cards are
ordered in groups of Clubs < Diamonds < Hearts < Spades, and then by rank within their suit (where A(Ace)< 2 < 3 < … < 10 < J(Jack) < Q(Oueen) < K(King)). For example, the array ["8H","10H","QD","JD","4S"] (i.e., 8 of Hearts, 10 of Hearts, Queen of Diamonds, Jack of Diamonds, 4 of Spades) is sorted into the sorted array: ["JD","QD","8H","10H","4S"].
This is the code I've been given as an answer but I do not understand what the second for-loop in the sortCards method is doing. If you're already going through the array in the first for-loop then what is the second doing?
public class Cards {
public static String[] sortCards(String[] s){ // SELECT SORT
for (int i = s.length - 1; i >= 1; i--){
// Find the maximum in the list[0..i]
String currentMax = s[0];
int currentMaxIndex = 0;
for (int j = 1; j <= i; j++) {
if (cardLessThan(currentMax,s[j])){
currentMax = s[j];
currentMaxIndex = j;
}
}
// Swap list[i] with s[currentMaxIndex] if necessary;
if (currentMaxIndex != i) {
s[currentMaxIndex] = s[i];
s[i] = currentMax;
}
}
return s;
}
static boolean cardLessThan(String s1, String s2){
char s1s = s1.charAt(s1.length()-1); //suites
char s2s = s2.charAt(s2.length()-1);
if(s1s < s2s)
return true;
else if(s1s > s2s)
return false;
// Same suite cards - order determined by card number
String n1 = s1.substring(0,s1.length()-1);
String n2 = s2.substring(0,s2.length()-1);
if(n1.equals("A") && !n2.equals("A")) return true;
if(n1.equals("2") && !n2.equals("A") && !n2.equals("2")) return true;
…
return false;
}`
This is similar to a BubbleSort algorithm, the inner loop is to find the value if any that needs to be swapped to the current slot of the array
here is an example using a number array
say you have 10 numbers in an array
1 2 5 7 8 3 4 6 9 0
you want to sort them from highest to lowest
after one iteration of the code you provided if it was set for integers would look like this
9 2 5 7 8 3 4 6 1 0
it found the 9 and swapped the 1 with it so the 9 is now at the top of the list
and it will do this for the entire array until the array looks like this
9 8 7 6 5 4 3 2 1 0
In a sort code when you need to replace a card at a position x you need to do a swap.
Here, first loop is doing loop for all your card and for each card the second loop try to see if the next one is greater then current, if yes swap is done
If no nothing happen.
Its pretty simple no?:)
You need to see algorithm about sort to understand clearly this.
Good luck;)

How to print an int array into a horizontal arrow?

Having an array such as int[] arr = new int[]{9, 6, 5, 2, 1, 2, 6, 3, 2, 7, 3, 8, 1, 5, 4, 7}; I want to print it like this:
* Output:
* 9
* 6 1
* 5 2 2
* 2 6 7 1
* 3 3 5
* 8 4
* 7
Without the * basically that's what I am trying to do. I intended to go over the array and just use System.out.println();until I reached then "end" which would be the 7 and then go to the next line but that didn't work.
I also tried printing 9 then 6 and 1 and so on but I couldn't make it to work either, I'm at a loss here and would appreciate guidance as to how can I think this through please.
EDIT
The intermediate step I have is making the array a "block" like this:
* Intermediate Step:
* 9 6 5 2
* 1 2 6 3
* 2 7 3 8
* 1 5 4 7
It should work for an array of any size.
I think this should work
You iterate 2 times. first you get the first row and all the diagonal rows below it, and then the last row and all the diagonal rows above it. You have to create a second array though to hold this info. I assumed that the array is same size for both X and Y. 7x7, 4x4 etc. tested with 4x4 data (your data)
String[][] array2 = new String[array.length*2][array.length];
for (int mb = 0; mb < array.length; mb++) {
String p1 = array[0][mb];
array2[mb][0] = p1;
int count = 0;
for (int i=1;i<=mb;i++) {
count++;
String p2 = array[i][mb-i];
array2[mb][count] = p2;
}
}
int counter = -1;
for (int mb = array.length -1; mb > 0; mb--) {
counter++;
String p1 = array[array.length -1][mb];
array2[mb+array.length -1][counter] = p1;
for (int i=0;i<counter;i++) {
String p2 = array[array.length -2 - i][array.length -counter + i];
array2[mb+array.length -1][i] = p2;
}
}
Well lets think you have two-dimensional array (you can change your one-dimension to two-dimensional easily)
PseudoCode :
whereToGo = RIGHT;
i = 0;
j = 0;
maxX = WIDTH;
maxY = HEIGHT;
minX = 0;
minY = 0;
while (somethingLeft){
addNumberToPyramid(array[i][j]);
if (whereToGo == RIGHT){
i++;
if (maxX == i) {
whereToGo = DOWN;
minY++;
}
} else if (whereToGo == DOWN){
//Same as if you go RIGHT, but increasing "j", at the end, you decrease maxY and then goLeft
} //... other two directions
}
This is how to parse input. Similar way for adding it to pyramid. I would prefer creating another 2D array, put that directly there as pyramid and then write method for printing this array correctly :
public class Pyramid{
//initialize minX, maxX etc.
int[][] array;
whereToGo = DOWN;
int i = 0, j = 0;
//initialize array size in constructor
public void addNumberToPyramid(int value){
if (whereToGo == DOWN){
array[i][j] == value;
j++;
if (j == maxY){
whereToGo = UPRIGHT;
maxY -= 2;
} else if (whereToGo == UPRIGHT){
} //... other else if directions
}
}
}
OK, first of all: You can't print a triangle like that for every length of an array. Say for example you had that array but missing the last entry; then your triangle would be missing one element at some point. In fact, you can print such a triangle if and only if the number of elements is the square of a natural number; in your example 16 = 4^2. Now, that 4 is also the length of your longest row.
OK, now how to do it. If you look at the intermediate step
9 6 5 2
1 2 6 3
2 7 3 8
1 5 4 7
and call that arr2, you want to print arr2[0][0] in the first row, arr2[1][0] and arr2[0][1] in the second row and so on until row 4 (which is of course the root of the length of the initial array). So you can write a nested loop that counts up like that.
Then you want to print arr2[1][3], arr2[2][2] and arr2[3][1] in the next row, then arr2[2][3] an arr2[3][2] and finally in the last row just arr2[3][3]. That is most easily done in a second nested loop.
I won't give you the exact code of course as this is obviously a learning task. But I will tell you that if you have a counter i for the outer loops and a counter j for the inner ones, the indexes in the intermediate array will depend on both i and j.

Matrix Multiplication Java

I need help, I am trying to make use of Lattice Multiplication in java for use in a BigInt class I am having to write for a class.
Right now I have the code storing the digits needed for the adding part of the algorithm in a 2 dimensional array. From there though I am at a lose as to how to make a loop to go through the array and add the numbers in what would be a diagonal.
For instance here is the test numbers etc:
200
*311
= 62200
The array is holding:
6 0 0
2 0 0
2 0 0
6 is (2,2) in the array and the bottom right is (0,0)
I need to add in a diagonal, such as (1,0) + (0,1) = 0
The issue is how do I do this, since not only is it moving up and left in different ways, but it goes from 1 element to 2 elements to 3 elements, then back the other way, and of course this will get bigger the longer the number is.
This is the code that I have:
public int multiply(BigInt val){
int[] bigger;
int[] smaller;
int[] dStore;
int lengthMax = (val.getSize()+this.getSize()) - 1;
int first = 0;
int second = 0;
int[][] tempResult;
//Checks to see which is bigger and then adds that to bigger
if(val.getSize() >= this.getSize()){
bigger = val.getData();
smaller = this.getData();
dStore = new int[val.getSize()+this.getSize()];
}else{
bigger = this.getData();
smaller = val.getData();
dStore = new int[val.getSize()+this.getSize()];
}
tempResult = new int[smaller.length][bigger.length];
for(int i=0;i < smaller.length;i++){
for(int j = 0;j < bigger.length;j++){
tempResult[i][j] = smaller[i] * bigger[j];
}
}
** there is the return statement etc below
This might help as to explain lattice multi better: Lattice Multi Video
I would try a different approach. Look at the lattice in the video and imagine that you rotates the array a little bit to the left so that the diagonals becomes vertical. The array would then look like this:
2 3 5
8 3
2 4 0
Now, just summarize the columns and you would have the total.
You would of course have to split the numbers into arrays of digits first. The easiest way to do that (but not the most efficient) is to convert them into strings ...
Good luck!
To move diagonally, you'd increment both x and y:
// Loop though the diagonal of an array
x = 0;
y = 0;
while (x < ARR_X_SIZE && y < ARR_Y_SIZE) {
// Do something with arr[x][y]
x++;
y++;
}
This is the basic loop; you can change the x and y increments to determine the direction you need to go. The key to going through the whole array is the value of the coordinates going into the loop. Array:
1 2 3
4 5 6
7 8 9
If you set x = 1; y=0 at the beginning of the loop, you'll get 2 6. Set x = 0, y = 1 and you'll get 4 8.
I hope this helps you with your assignment. Good luck on the rest! That is definately an interesting algorithm to implement.

Searching specific rows in a multi-dimensional array

I'm new to java programming and I can't wrap my head around one final question in one of my assignments.
We were told to create a static method that would search a 2-D array and compare the numbers of the 2-D array to an input number...so like this:
private static int[] searchArray(int[][] num, int N){
Now, the part what we're returning is a new one-dimensional array telling the index of the first number in each row that is bigger than the parameter variable N. If no number is bigger than N, then a -1 is returned for that position of the array.
So for example a multi-dimensional array named "A":
4 5 6
8 3 1
7 8 9
2 0 4
If we used this method and did searchArray(A, 5) the answer would be "{2,0,0,-1)"
Here is a very good explanation about Java 2D arrays
int num[][] = {{4,5,6},{8,3,1},{7,8,9}};
int N = 5;
int result[] = new int[num.length];
for(int i=0; i<num.length; i++){
result[i] = -1;
for(int j=0; j<num[0].length; j++){
if( N < num[i][j] ){
result[i] = j;
break;
}
}
}
for(int i=0; i<result.length; i++){
System.out.println(result[i]);
}
The first for loop(The one with a for inside it) traverses the 2D array from top to bottom
in a left to right direction. This is, first it goes with the 4 then 5,6,8,3,1,7,8,9.
First the result array is created. The length depends of the number of rows of num.
result[i] is set to -1 in case there are no numbers bigger than N.
if a number bigger than N is found the column index is saved result[i] = j and a break is used to exit the for loop since we just want to find the index of the first number greater than N.
The last for loop just prints the result.
Generally when using multi-dimensional arrays you are going to use a nested for loop:
for(int i = 0; i < outerArray.length; i++){
//this loop searches through each row
for(int j = 0; j < innerArrays.length; j++) {
//this loop searches through each column in a given row
//do your logic code here
}
}
I won't give you more than the basic structure, as you need to understand the question; you'll be encountering such structures a lot in the future, but this should get you started.

Categories

Resources