We have triangle made of blocks. The topmost row has 1 block, the next row down has 2 blocks, the next row has 3 blocks, and so on. Compute recursively (no loops or multiplication) the total number of blocks in such a triangle with the given number of rows.
triangle(0) → 0
triangle(1) → 1
triangle(2) → 3
This is my code:
public int triangle(int rows) {
int n = 0;
if (rows == 0) {
return n;
} else {
n = n + rows;
triangle(rows - 1);
}
}
When writing a simple recursive function, it helps to split it into the "base case" (when you stop) and the case when you recurse. Both cases need to return something, but the recursive case is going to call the function again at some point.
public int triangle(int row) {
if (row == 0) {
return 0;
} else {
return row + triangle(row - 1);
}
}
If you look further into recursive definitions, you will find the idea of "tail recursion", which is usually best as it allows certain compiler optimisations that won't overflow the stack. My code example, while simple and correct, is not tail recursive.
You are not making use of the return value of your function. Instead you always declare a new local variable. Otherwise your solution is quite close to the correct one. Also you should add another return in case you are not at row 0.
public static int triangle (int rows) {
int n = 0;
if (rows == 0) {
return n;
} else {
n = n + rows;
n = n + triangle(rows - 1);
}
return n;
}
Related
I want to solve N Rooks problem in N x N board using recursion with max N = 8. My code works fine for N = 2, 3, 4, 5, 6, 7. But when N = 8 it gives so many possible results starting with the first row of 1 0 0 0 0 0 0 0 then gives stackoverflow error before checking other possible results starting with the first row of 0 1 0 0 0 0 0 0.
I know about general recursion like fibonacci series, factorial, etc. and I can trace them down. Then I came across a new form of recursion called backtracking recursion. Then I sarted to learn the logic behind this form of recursion and read some pseudocode algorithms. Acually this form of recursion seemed to me a little bit harder to construct than normal recursion.
public class NRooks {
/**
* In this code r = which row, c = which column.
* lastY method just returns column c of last placed rook in
* a given row r in order to remove it.
* row.length, col.length, board.length have no special meaning. They all
* equal to the dimension of board N.
* main() method always initiates first row(r = 0). Therefore in main()
* method r remains 0 and c changes as you can see in putRook(0, i).
* So solve() method always begins from second row(r = 1).
*/
private static int found = 0;
private static int[][] board;
private static int[] row;
private static int[] col;
public static void putRook(int r, int c) {
board[r][c] = 1;
row[r] = 1;
col[c] = 1;
}
public static void removeRook(int r, int c) {
board[r][c] = 0;
row[r] = 0;
col[c] = 0;
}
public static boolean isValid(int r, int c) {
if (row[r] == 0 && col[c] == 0) return true;
return false;
}
public static void showBoard() {
for (int r = 0; r < board.length; r++) {
for (int c = 0; c < board.length; c++) {
System.out.print(board[r][c] + " ");
}
System.out.println();
}
System.out.println();
}
public static int lastY(int r) {
for (int j = 0; j < board.length; j++) {
if (board[r][j] == 1) return j;
}
return -1;
}
public static boolean solve(int r, int c) {
int last;
if (r == 0) return false;
if (r == col.length) {
found++;
/**
* When I dont include below printline statement my code
* works fine until N = 7 then gives SO error.
* But When I include this print statement in order
* to print number of results my code works fine until
* N = 6 then gives SO error
*/
//System.out.println("Found: " + found);
showBoard();
r--;
last = lastY(r);
removeRook(r, last);
c = last + 1;
}
for (int j = c; j < row.length; j++) {
if (isValid(r, j)) {
putRook(r, j);
return solve(r + 1, 0);
}
}
last = lastY(r - 1);
removeRook(r - 1, last);
return solve(r - 1, last + 1);
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
board = new int[n][n];
row = new int[n];
col = new int[n];
for (int i = 0; i < row.length; i++) {
boolean finished; // not important
putRook(0, i);
finished = solve(1, 0);
if (finished) System.out.println("============"); // ignore this too
}
}
}
Stackoverflow points to the lines that contain recursive calls to solve() method.
Note: I know only C like syntax of java and basic data abstraction. I wrote this code with this level of my Java.
I want to solve this problem and N queens problem myself.
Because there are so many solutions to these problems out there, both mathematically and algorithmically. And I am not interested in advanced Java data abstraction things right now.
I only want some advice about my code snippet above something like
Your backtracking algorithm is not efficient. (so straightfoward)
You need to use some Java data abstraction things to solve this problem efficiently.
You need to use another form of recursion like tail recursion (I heard about this too.)
....
The main issue why you're getting Stack Overflow error is the way your recursion is structured. The moment solve is invoked in the main method, it keeps recursing deeper and deeper; in fact, all of its invocations form a single several-thousand-calls-deep chain. For n=7, there are 3193 nested calls (I added a counter to check this). For n=8, it performs about 5k recursive calls before overflowing stack on my machine - I guess stack size is rather small by default.
Thus, to get this to work for higher values of n, you need to restructure your recursion in a way that doesn't perform all the recursive calls as a single chain. I could argue that your current solution isn't really backtracking because it never actually backtracks. Let me illustrate what backtracking means on a simpler problem. Let's say you want to print all binary strings of length n=3 ("000" through "111") programmatically, without relying on knowing the value of n. An implementation for this could be something like this:
def build_binary_string(current_prefix, chars_left):
if chars_left == 0:
print current_prefix
return
build_binary_string(current_prefix + 'a', chars_left - 1)
build_binary_string(current_prefix + 'b', chars_left - 1)
build_binary_string("", 3)
The interesting thing (backtracking!) happens at the moment when build_binary_string is invoked with arguments ("00", 1):
build_binary_string("000", 0) is invoked, prints "000" and returns immediately
we are back into build_binary_string("00", 1) function call, right about to execute build_binary_string(current_prefix + 'b', chars_left - 1)
build_binary_string("001", 0) is invoked, prints "001" and returns immediately
That point when control flow returned from build_binary_string("000", 0) to build_binary_string("00", 1) and it chose to make another function call was backtracking. Note that the depth of recursion never exceeded 3.
I cannot test your code as I do not have some of your methods, but is the int j = c supposed to be int j = r?
for (int j = c; j < row.length; j++) {
if (isValid(row, col, r, j)) {
putRook(b, row, col, r, j);
return solve(b, row, col, r + 1, 0);
}
}
Inside of this line you are passing 0 to c then declaring j=c in the for loop conditions so j < row.length will be true every time. I do not know what your isValid() is though.
return solve(b, row, col, r + 1, 0);
EDIT: I see now the c is being declared in the if block above, but if that if block does not get executed this should be an infinite loop afterward. Maybe check to see if r == col.length is executing correctly.
I'm trying to write a method that takes a 2D array(arranged so that the elements in every row are in increasing order from left to right, and the elements in every column are in increasing order from top to bottom) and an int, and sees if the int is in the 2D array. I wanted to use nested loops, but that would make it go in O(N^2) time. I'm therefore trying to make conditionals that make it so it tests if the int is smaller than the first in one of the sub arrays and bigger than the last, and if so, goes onto the next subarray. Here's what I have:
static boolean has(int number, int[][] a) {
int q = 0;
boolean c = false;
for (int i = 0; i < a[q].length-1; i++){
if ((number < a[i][q]) || (number > a[a[j].length-1][i])){
q++;
}
else if (number == a[i][q]){
c = true;
break;
}
else c = false;
}
return c;
}
could use some help. This method compiles but gives me outOfBounds Thanks!
This solution runs in O(n+m):
static boolean has(int number, int[][] a) {
int row = 0;
int col = a[0].length - 1;
while (row < a.length && col >= 0) {
int n = a[row][col];
if (n < number) {
row++;
} else if (n > number) {
col--;
} else {
return true;
}
}
return false;
}
You can solve this in O(log(n) + log(m)) first find the row that contain the integer you're looking for using binary search (since columns are sorted), then find the exact position of the integer in that row, by performing another binary search (since rows are sorted).
I need to get a number of all possible ways to divide array into small sub-arrays. We can divide array verticaly and horizontaly. My algorithm works very good, but time complexity is too bad. Can you have a look how to improve it?
Parameters
nStart - first row of sub-array
nEnd - last row of sub-array
mStart, mEnd - are for second dimension (columns).
check() - functions checking end condition
return - numbers of different ways to divide array. We divide while function check return true.
public static long divide(int nStart, int nEnd, int mStart, int mEnd) {
long result = 0;
for(int i = 1; i < nEnd - nStart; i++) {
if(check(nStart, nStart + i, mStart, mEnd) && check(nStart + i, nEnd, mStart, mEnd))
result += divide(nStart, nStart + i, mStart, mEnd) * divide(nStart + i, nEnd, mStart, mEnd);
}
for(int i = 1; i < mEnd - mStart; i++) {
if(check(nStart, nEnd, mStart, mStart + i) && check(nStart, nEnd, mStart + i, mEnd))
result += divide(nStart, nEnd, mStart, mStart + i) * divide(nStart, nEnd, mStart + i, mEnd);
}
return (result == 0 ? 1 : result) % 1000000000;
}
Example
Input
2 2
10
01
Output 2
Input
3 2
101
010
Output 5
I think you need to know how check() function works. We stop dividing when next subarray have only ones or only zeros. Here is code:
public static boolean check(int nStart, int nEnd, int mStart, int mEnd) {
if((nEnd - nStart) + (mEnd - mStart) == 2)
return false;
for(int i = mStart; i < mEnd; i++) {
for(int j = nStart; j < nEnd; j++) {
if(bar[i][j] != bar[mStart][nStart])
return true;
}
}
return false;
}
By looking at your code I can see that in each step of the recursion you divide your two-dimensional array into two arrays with a single horizontal or vertical cut. Then you verify that both of these parts fulfil some condition of yours defined by the check-method and, if so, then you put these two parts into a recursion. When the recursion can no longer be continued, you return 1. Below I assume that your algorithm always produces the result you want.
I'm afraid that an effective optimization of this algorithm is highly dependent on what the check-condition does. In the trivial case it would always retuns true, when the problem collapsed into a straightforward mathematical problem that propably has a general non-recursive solution. A bit more complex, but still effectively solvable would be a scenario where the condition would only check the shape of the array, meaning that e.g. check(1,5,1,4) would return the same result as check(3,7,5,8).
The most complex is of course a general solution, where the check-condition can be anything. In this case there is not much that can be done to optimize your brute force solution, but one thing that comes to my mind is adding a memory to you algorithm. You could use the java.awt.Rectangle class (or create your own class) that would hold the dimensions of a sub-array and then have a java.util.HashMap to store the results of the executions of the divide-method for furure reference, if the method is called again with the same parameters. This would prevent duplicate work that will propaply occur.
So you define the haspmap as a static variable in you class:
static HashMap<Rectangle,Long> map = new HashMap<Rectangle,Long>();
then in the beginning of the divide-method you add the following code:
Rectangle r = new Rectangle(nStart,mStart,nEnd,mEnd);
Long storedRes = map.get(r);
if (storedRes != null) {
return storedRes;
}
and then you change the ending of the method into form:
result = (result == 0 ? 1 : result) % 1000000000;
map.put(r, result);
return result;
This should give a performance-boost for your algorithm.
To return to my earlier tought, if the check-condition is simple enough, this same optimization can be done even more effectively. For example, if your check-condition only checks the shape of the array, you will only need to have its width and height as a key to the map, which will decrease the size of the map and multiple the number of positive hits in it.
we got a matrix size of NxN which is represented by a multidimentional array, the matrix contains integer numbers, we assume that N=2^K.
We can also say that the matrix is ordered by cutting the matrix to 4 quarters (image below), every element in the first quarter is smaller or equal to the element in the second quarter, every element in the second quarter is smaller or equal to the third quarter, and every element in the third quarter is smaller or equal to every element in the forth quarter. (and so on recursivly)
like this:
1 2
3 4
Example of sorted matrix:
We need to write a function that returns true if the num exist in the matrix.
and to make it as most efficient as possible.
I've wrote the following function:
public static boolean isExist(int[][] mat, int num)
{
int start_rows = 0;
int start_columns = 0;
// If more then 4 elements
// Loop log(base 4)n
for (int elements_size = mat.length * mat[0].length, table_size, quarter_size,
quarter1, quarter2, quarter3, quarter4;
(elements_size > 4);
elements_size /= 4)
{
table_size = (int)(Math.sqrt(elements_size));
quarter1 = mat[start_rows+(table_size/2)-1][start_columns+(table_size/2)-1];
quarter2 = mat[start_rows+(table_size/2)-1][start_columns+table_size-1];
quarter3 = mat[start_rows+table_size-1][start_columns+(table_size/2)-1];
quarter4 = mat[start_rows+table_size-1][start_columns+table_size-1];
if (num == quarter1 || num == quarter2 || num == quarter3 || num == quarter4) {
return true;
}
// Decrease elements_size
quarter_size = (int)Math.sqrt(elements_size/4);
if (quarter1 > num) {
// Dont do anything
} else if (quarter2 > num) {
start_columns += quarter_size; // Increase columns
} else if (quarter3 > num) {
start_rows += quarter_size; // Increase rows
} else if (quarter4 > num) {
start_rows += quarter_size; // Increase rows
start_columns += quarter_size; // Increase columns
} else {
return false; // bigger then quarter, fail.
}
}
return (mat[start_rows][start_columns] == num || mat[start_rows+1][start_columns] == num ||
mat[start_rows][start_columns+1] == num || mat[start_rows+1][start_columns+1] == num);
}
Is that the most efficient way to do so?
Also its time complexity is O(logn). (am I correct?)
well, that is a good approach!
if i understood you right, you want to find out if the array includes a specific int-value;
well, i would use the following methode (but you have to match this to a int [][] array):
HashSet<Integer> test= new HashSet<Integer>(Arrays.asList(intArray));
test.contains(intValue)
this approach is pretty fastest because the hashcode-mechanism has the complexity O(1) but i think through the asList()- it leads to arraylist complexity O(n)... not sure about this!!
It can be done in time complexity O(n). I am not sure if the post is still active. But below is my solution to do it in O(n).
public class NumberInMatrix {
public static void main(String args[]){
int matrix[][] = {{-4,-2,5,9},
{2,5,12,13},
{13,20,25,25},
{22,24,49,57},};
System.out.println(isExist(matrix, 1));
}
private static String isExist(int[][] matrix, int numberToBeSearched) {
int rowCounter = 0, colCounter = matrix[0].length - 1;
while(rowCounter < matrix.length && colCounter >= 0){
if(numberToBeSearched == matrix[rowCounter][colCounter]){
return "Number exist";
}else{
if(numberToBeSearched > matrix[rowCounter][colCounter]){
rowCounter++;
}else{
colCounter--;
}
}
}
return "Number does not exist";
}
}
A method, printStars(j), is available that returns a string -- a row of j asterisks. I need to write a method that recursively prints a triangle of n rows of asterisks. The first row needs to have one *, the second have two *s, etc. No iterative loops can be used (so no while, do-while, or for).
The code to do it backwards is simple enough:
public void printTriangle(int n) {
if(n >= 1) {
printStars(n));
printTriangle(n - 1);
}
}
My code thus far for the above but reversed is below. It is incorrect as i is reset to 1 in each loop. I'm just not sure how to go about it. I can only use a one-parameter function.
public void printTriangle(int n) {
int i = 1;
if(i <= n) {
printStars(i);
printTriangle(i + 1);
}
}
Just first recur, then print the line:
public void printTriangle(int n) {
if(n > 1) {
printTriangle(n - 1);
}
System.out.println(makeStars(n));
}
So the smaller triangle is printed first, and then the longer line appended.
static int i = 1;
This will ensure that i retains its value between calls to the function.
It is initialized to 1 the first time, and any changes made to the variable will persist across calls.
EDIT: As the comment says, this isn't the right way. Daniel Fischer's solution is better.
Pass the maximum value of i as a second parameter to limit the number of lines to print i.e. the maximum value for i.
Maybe a two parameters function:
public void printTriangle(int i, int n) {
if(i <= n) {
System.out.println(printStars(i));
printTriangle(i+1, n);
}
}