Big O notation of recursion function called inside for loop - recursion

I'm trying to determine the big O complexity of several algorithms and I'm having trouble understanding how to reason about the following piece of code:
void recursiveFunc (n)
{
for(int i = 0; i < 8; i++)
{
if (n < maxN)
{
recursiveFunc (n + 1);
}
else
{
for(int j = 0; j < 8; j++)
{
// do some stuff
}
}
}
}
I have the idea this is an exponential since the recursive function is called inside the loop. O(8^n)?
But I'm a bit lost on how to reason about it.

Your tip is correct.
Given the code:
var maxN = 16;
var initN = 0;
var count = 0;
function recursiveFunc (n) {
for(var i = 0; i < 8; i++) {
if (n < maxN) {
recursiveFunc (n + 1);
} else {
for(int j = 0; j < 8; j++) {
count++;
}
}
}
}
recursiveFunc(initN);
First call happens with n = 0:
8^1 calls of recursiveFunc (where n = 1)
calls with n = 1 then cause: 8^2 calls of recursiveFunc
...
calls with n = (maxN - 1) then cause: 8^maxN calls of recursiveFunc => visiting else branch, each call enters "some stuff" 64 times
First call happens with n = 2, maxN = 4:
8^1 calls of recursiveFunc (where n = 3)
calls with n = 3 then cause: 8^2 calls of recursiveFunc (where n = 4)
calls with n = 4 then visit else branch, each 64 times.
Therefore total count of entering the "some stuff" stage: 64 * (8^(maxN - initN))
O(8^n)
EDIT: You can see this in work here, just click "Run the snippet" and then hit the "Test" button. (Trying bigger maxN values may crash your browser)
function test () {
var maxN = parseInt(document.querySelector("#nmax").value);
var initN = parseInt(document.querySelector("#n").value);
var count = 0;
function recursiveFunc (n) {
for(var i = 0; i < 8; i++) {
if (n < maxN) {
recursiveFunc (n + 1);
} else {
for(var j = 0; j < 8; j++) {
count++;
}
}
}
}
recursiveFunc(initN);
document.querySelector("#expectedValue").innerHTML = 64 * (Math.pow(8, maxN - initN));// 64 * (8^(maxN - initN));
document.querySelector("#realValue").innerHTML = count;
}
N: <input type=number id=n value=0><br>
NMAX: <input type=number id=nmax value=5><br>
<hr>
Expected value: <span id=expectedValue></span><br>
Real value: <span id=realValue></span><br>
<button onclick="test()">Test</button>
(I also assume that initN <= maxN)

Related

How would this shell-sort algorithm be coded in recursive?

I understand that any iterative function can be written recursively, but I still don't quite understand how to write it as a recursive function.
This function receives an array (elements) and a int (number of elements), and sorts them from lower to higher, but I don't get how to make it recursive, any help would be appreciated!
void ShellSort(int *arr, int num){
for (int i = num / 2; i > 0; i = i / 2)
{
for (int j = i; j < num; j++)
{
for(int k = j - i; k >= 0; k = k - i)
{
if (arr[k+i] >= arr[k])
{
break;
}
else
{
arr[k]=arr[k] + arr[k+i];
arr[k+i]=arr[k] - arr[k+i];
arr[k]=arr[k] - arr[k+i];
}
}
}
}
return ;
}

Setting Base Cases for Recursive Function

class Solution {
//given a location on the matrix, this function recursively find the deepest possible depth, which is the length of a side of a found square
private int isSquare(int row_index, int col_index, int depth, char[][] matrix) {
int last_row = row_index + depth;
int last_col = col_index + depth;
if (row_index >= matrix.length || col_index >= matrix[0].length) {
return 0;
}
if (last_row >= matrix.length || last_col >= matrix[0].length) {
return 0;
}
for (int i = col_index; i < last_col; i++) {
if (matrix[row_index][i] != '1') {
return 0;
}
}
for (int i = row_index; i < last_row; i++ ) {
if (matrix[i][col_index] != '1') {
return 0;
}
}
return Math.max(depth, isSquare(row_index, col_index, depth + 1, matrix));
}
public int maximalSquare(char[][] matrix) {
int max = 0;
for (int row = 0; row < matrix.length; row ++) {
for (int col = 0; col <matrix[0].length; col ++) {
int curr_depth = isSquare(row, col, 1, matrix);
if (curr_depth > max) {
max = curr_depth;
}
}
};
return max * max;
}
}
Hi, I was working on LeetCode 221, and it seems like that my solution is not passing test cases with output 1, where the biggest square on the given matrix is just 1 x 1. To me it looks like those depth 1 cases are not passing the two for loops in function isSquare, which is supposed to catch 0s in the square.
I tried LC debugging tool but it did not help much, and my base cases seem fine to me. Please let me know what is going on here. For the problem, https://leetcode.com/problems/maximal-square/
One of the depth 1 test cases that I am failing is below.
Input:
[["0","1"],["1","0"]]
Output:
0
Expected:
1

Firebase (....ContinueWith(task => ...) in a For-Loop

First, this is the code:
for (int j = 1; j <= count; j++)
{
db.Child("Some Child").GetValueAsync().ContinueWith(task =>
{
Debug.Log("j: " + j); // Here the Debug will show me that j = count
if (task.IsFaulted)
{
// ERROR HANDLER
}
else if (task.IsCompleted)
{
// Some Code Here
}
});
}
Ok, so my problem is that after the "....ContinueWith(task => ..." ' j ' will become directly equal to the count variable. Why this happens and how to solve it? Or is there another method to do that?
Ok, so my problem is that after the "....ContinueWith(task => ..." ' j
' will become directly equal to the count variable. Why this happens
and how to solve it?
That's because you used <= instead of <. With <=, j must be equals to count for the loop condition to be met and finish. If you want j to be less than count then use count-1 or simply use <.
So, that should be
for (int j = 1; i <= count-1; j++)
Or
for (int j = 1; i < count; j++)
Note that array starts from 0 not 1 so int j = 1; should be int j = 0; but I have a feeling that's what you wanted to do and you are starting the loop from 1 on purpose.
Finally, another problem is your variable being captured in a loop because you are using lambda in the ContinueWith function. See this post for more information. To use the j variable inside the ContinueWith lambda function, make a copy of it then use that copy instead of the j variable.
db.Child("Some Child").GetValueAsync().ContinueWith(task =>
{
//MAKE A COPY OF IT
int jCopy = j;
Debug.Log("j: " + jCopy); // Here the Debug will show me that j = count
}
Complete fixed code:
for (int j = 1; i < count; j++)
{
db.Child("Some Child").GetValueAsync().ContinueWith(task =>
{
//MAKE A COPY OF IT
int jCopy = j;
Debug.Log("j: " + jCopy);
if (task.IsFaulted)
{
// ERROR HANDLER
}
else if (task.IsCompleted)
{
// Some Code Here
}
});
}

Unhandled exception error with two dimensional array

This dynamic programming algorithm is returning unhandled exception error probably due to the two dimensional arrays that I am using for various (and very large) number of inputs. I can't seem to figure out the issue here. The complete program as follows:
// A Dynamic Programming based solution for 0-1 Knapsack problem
#include<stdio.h>
#include<stdlib.h>
#define MAX 10000
int size;
int Weight;
int p[MAX];
int w[MAX];
// A utility function that returns maximum of two integers
int maximum(int a, int b) { return (a > b) ? a : b; }
// Returns the maximum value that can be put in a knapsack of capacity W
int knapSack(int W, int wt[], int val[], int n)
{
int i, w;
int retVal;
int **K;
K = (int**)calloc(n+1, sizeof(int*));
for (i = 0; i < n + 1; ++i)
{
K[i] = (int*)calloc(W + 1, sizeof(int));
}
// Build table K[][] in bottom up manner
for (i = 0; i <= n; i++)
{
for (w = 0; w <= W; w++)
{
if (i == 0 || w == 0)
K[i][w] = 0;
else if (wt[i - 1] <= w)
K[i][w] = maximum(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]);
else
K[i][w] = K[i - 1][w];
}
}
retVal = K[n][W];
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return retVal;
}
int random_in_range(unsigned int min, unsigned int max)
{
int base_random = rand();
if (RAND_MAX == base_random) return random_in_range(min, max);
int range = max - min,
remainder = RAND_MAX % range,
bucket = RAND_MAX / range;
if (base_random < RAND_MAX - remainder) {
return min + base_random / bucket;
}
else {
return random_in_range(min, max);
}
}
int main()
{
srand(time(NULL));
int val = 0;
int i, j;
//each input set is contained in an array
int batch[] = { 10, 20, 30, 40, 50, 5000, 10000 };
int sizeOfBatch = sizeof(batch) / sizeof(batch[0]);
//algorithms are called per size of the input array
for (i = 0; i < sizeOfBatch; i++){
printf("\n");
//dynamic array allocation (variable length to avoid stack overflow
//calloc is used to avoid garbage values
int *p = (int*)calloc(batch[i], sizeof(int));
int *w = (int*)calloc(batch[i], sizeof(int));
for (j = 0; j < batch[i]; j++){
p[j] = random_in_range(1, 500);
w[j] = random_in_range(1, 100);
}
size = batch[i];
Weight = batch[i] * 25;
printf("| %d ", batch[i]);
printf(" %d", knapSack(Weight, w, p, size));
free(p);
free(w);
}
_getch();
return 0;
}
Change this:
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return K[size][Weight];
To this:
int retVal;
...
retVal = K[size][Weight];
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return retVal;

Changing method to be completely recursive

void merge(List<E> l, int lower, int upper) {
ArrayList<E> array = new ArrayList<E>();
for (int i = lower; i <= upper; i++)
array.add(list.get(i));
int front= 0;
int front2= (array.size() + 1) / 2;
for (int i = lower; i <= upper; i++) {
if (front2 >= array.size() ||
(first < ((array.size() + 1) / 2) &&
(array.get(first).compareTo(array.get(second)) <= 0))) {
l.set(i, array.get(front));
front++;
}// end if
else {
l.set(i, array.get(front2));
front2++;
}
}
}
This is my method. I want to change it to be completely recursive(I don't want to use for loops), but I simply don't see how. Is there a way to make this recursive or avoid using loops?

Resources