I'm having a bit of trouble understanding the concept of recursion. I understand that it is basically a method that calls itself and turns a big problem into a bunch of smaller parts to solve it. What I'm having difficulty with is using recursion with an array. Here is an example in my book:
//Precondition: x is an array of n integers
public int recur(int[] x, int n)
{
int t;
if(n == 1)
return x[0];
else
{
t = recur(x, n-1);
if(x[n-1] > t)
return x[n-1];
else
return t;
}
}
If anyone has the time, could you explain what this method does and how it works? Greatly appreciated!
This function returns the largest integer of an integer array.
Lets see how, Your function recur takes an integer array x and its length n.
If the length of array is 1 then the lone element x[0] is the largest one.
Else we get the largest element from the array starting with x[0] to x[n-2](that is array of length n - 1) and so on, when we get the largest element we keep on sending it as the return value till recursion finishes, finally returning the largest value.
This method finds the biggest number among the first n elements of an array.
It works by finding the biggest number among the first n-1 elements; then checking whether the nth element is bigger. The recursion comes in when it finds the biggest number in the first n-1 elements - it does that by calling itself with n-1 in place of n.
Of course, if n is 1, then there's nothing to check - we should just return the first element. This is the "base case" of the recursion.
Note that when I say the nth element, this is actually x[n-1], not x[n] because array indexes start from zero.
In recursion we have what is called base case which is a condition to make the recursion stop. In this situation the base case is if (n==1) where the first element of x[] is returned.
Let's go to the second part of the recursion. The function is calling itself but decrementing n, until it reachs to the base case. Once the base case is returned, the function will compare the first element, now t, with the next one x[n-1] (where n is equal to 2) and return the greater of both. When one value is returned the function goes to its previous call in the stack.
In other words, to analize recursion you should go through the function calls until the base case is reached and once there, start to go back leaded by the returns or the final execution of the function.
As stated in above answers this method will return largest among the first n values in the array, i would like to show this answer pictorially
Assume array with values
{5, 4, 2, 1, 8, 6, 4, 2, 12, 33}
-----------------------------------------------------------------------------------
caller | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
===================================================================================
t | 12 | 8 | 8 | 8 | 8 | 5 | 5 | 5 | 5 | none
===================================================================================
return | 33 | 12 | 8 | 8 | 8 | 8 | 5 | 5 | 5 | 5
Here caller is the invoker of recursive method. and in the n = 10, 33 will be compared with 12 and 33 will be returned to invoker. Hence invoker will received largest value in the array.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm working on a simple algorithm of trying to find the kth to last element from the Linearly Linked Lists
However, at my solution, it's not outputting the correct number that I expect.
I know how to solve the problem, but I'm wondering why doesn't the head recursion work the way I intended. And I would appreciate it if I receive another pair of eyes.
Wrapper function
public int findKthToLast(int kth){
//If zero items in the list
if(head == null){
System.out.println("List is empty");
return 0;
}
//If 1 item in the list
if(head.getNext() == null){
System.out.println("Only 1 item in the list which is: " + head.getData());
return 0;
}
//Allocating an array of size 1. This will help me keep track on what kth element when I go back from the recursion
int[] array = new int[1];
array[0] = -1;
//the '1' below represents the length. it will increment as you see in the recursive solution
return findKthToLast(head,kth,1,array);
}
Recursion
public int findKthToLast(Node head,int kth,int length, int [] array){
//if final item in the list
if(head.getNext() == null){
//if kth element is greater then total length just return 0
if(kth >= length){
return 0;
}
//kth = 0 means output the final item in the list. returns head.data
if(kth == 0){
return head.getData();
}
//when I backtrack from the stack I need to know if the kth to final element is equal to length. That's where the array comes from
array[0] = length - kth;
return 0;
}
int element;
element = findKthToLast(head.getNext(),kth,++length,array);
//if equal then I'm done. return the head.data
if(length == array[0]){
return head.getData();
}
return element;
}
the Problem:
In the list: 8 -> 4 -> 2 -> 1. If kth = 1 (I want the item before last so in this case the value "2") the output should be "2". However, in my current code, I'm receiving 1 number higher so the value "4"
I don't want the correct code. I know if I changed my base case from
if(head.getNext() == null)
to
if(head == null)
then my code works completely fine. What I want is why doesn't my current solution work. Am I visualizing the call stack incorrectly? Thank you
You probably outsmarted yourself because you have a really perverse way of computing the length of your list on each recursion call. Instead of just adding one to the current length, you modified the length variable so that you correctly pass in the increased length into the next recursive call... however you then use that incremented length when your function pops out, causing you to miscount.
Let's step through the example below:
8 -> 4 -> 2 -> 1
findKthToLast(8, 1, 1, [-1])
|
|-> 8.next is NOT null
|
| element = findKthToLast(4, 1, ++1, [-1])
|
| -> 4.next is NOT null
|
| element = findKthToLast(2, 1, ++2, [-1])
|
| -> 2.next is NOT null
|
| element = findKthToLast(1, 1, ++3, [-1])
|
| -> 1.next IS null
| kth is NOT 0
| => array[0] <- 4 - 1 = 3 (correct)
| return 0
| element = 0
| length is 4 != 3 because of prefix increment (length should be 3 but you incremented before calling the function)
| return 0
| element = 0
| length is 3 == 3 because of prefix increment, so return current node
| return 2 (not correct but this is what you told the code to do)
| element = 2
| length is 2 != array[0]
| return 2
| return 2
Personally, I'd go for a two pointer slow/fast approach, but if you must use recursion, then I would make it easier on myself and maintain a length counter that is incremented in the back (the last element returns 0, then on subsequent calls return element + 1) and store the correct value in the array instead.
public static int exponent(int baseNum, int exp) {
if (exp == 0) return 1;
else return baseNum * exponent(baseNum, --exp);
}
I don't understand how the two parameters work in this recursive method. Is baseNum value transfered to exponent multiplied by baseNum then returned? Then the second parameter (exp) does the same until it reaches the base case?
If you could help me visualize or break down how this works that would be great! Thank you.
Here is an example call to this recursive method using 2 and 4 for the arguments~(:
exponent(2, 4)
=> 2 * exponent(2, 3)
=> 2 * exponent(2, 2)
=> 2 * exponent(2, 1)
=> 2 * exponent(2, 0) <- exp == 0, returns 1 so no more recursive calls
so working back up the chain:
2 * (1) => 2
2 * (2) => 4
2 * (4) => 8
2 * (8) => 16
A problem with this particular method is that if you were to pass in a negative value for exp on first call, you would get infinite recursion. Better to check (exp <= 0) instead
Recursive method exponent() calls itself if second argument exp is not 0, and uses returned result in further calculation. By each call, exp is decreased by 1, so finally (if initially > 0) it meets terminal condition.
A simple sequence diagram to illustrate:
exponent(2, 3)
| ----------> exponent(2, 2)
| | ----------> exponent(2, 1)
| | | ----------> exponent(2, 0)
| | | <---------- returns 1 // terminal condition
| | <---------- returns 2 * 1 = 2
| <---------- returns 2 * 2 = 4
returns 2 * 4 = 8
When you call the method the first time, say exponent(10,5) this means the recursive method gets called 5 times.
Each time exp is reduced by 1 right before calling the recursive method. The parameters are passed into the method. They are local variables, so they only exist inside the method.
exponent(10,5)
will call
else return 10 * exponent(10,4)
then
else return 10 * exponent(10,3)
then
else return 10 * exponent(10,2)
… etc
until exp ==0.
exponent() is a method for calculating a number (baseNum) to the power of another number (exp) by simply multiplying the number with itself exp number of times.
If the exponent is 0, then it will return 1 since every integer to the power of 0 equals 1 (with the exception of 0 itself, which is not covered for some reason).
Let us say that we want to calculate 2^3. We will call the method by writing exponent(2,3). What happens is the following:
return 2*exponent(2,2);
Since exponent(2,2)is the same thing as return 2*exponent(2,1);, we can instead write it as the following:
return 2*2*exponent(2,1);
exponent(2,1) is the same thing as 2*exponent(2,0) which is 2*1 (when exp is 0, we return 1). So we can instead write this as return 2*2*2*1;
So we wanted to calculate 2^3 and the method called itself three times and multiplied 2 with itself every time and finally returned the answer of 2*2*2*1.
Do not forget that 0^0 is not 1. If you call exponent(0,0) you will get 1 which is wrong.
I'm working on an textbook assignment and am having trouble understanding arrays. I'm looking at a practice question and am confused.
Declare an array of integers containing the first five prime numbers.
This would be int[]primes = {2,3,5,7,11}
Assume the array 'primes' has been initialized. What does it contain after executing the following loop?
for(int i = 0; i < 2; i++)
{
primes[4 - i] = primes[i];
}
The textbook gives the answer {2,3,5,3,2} for this...can anyone explain how this loop works?
I assume you understand practice 1. For practice 2, the loop
for (int i = 0; i < 2; i++)
iterates twice: once at i=0, and once at i=1. At i=2, the condition i<2 is broken, and the loop does not execute.
The actual line of code inside the loop
primes[4-i] = primes[i];
sets the 4-i'th element in the array to be equal to the i'th element in the array.
Initialized, the array primes is {2,3,5,7,11}
After one loop, the array primes is {2,3,5,7,2} (primes[4] = primes[0] has been executed).
After both loops, the array primes is {2,3,5,3,2} (primes[3] = primes[1] has been executed).
Remember that arrays are indexed by zero. Hope this helped.
the for loop exceutes two times, for i=0 and i=1
primes[4-0] = primes[0] = 2 -> primes[4] = 2
primes[4-1] = primes[1] = 3 -> primes[3] = 3
so the first 3 fields in the array are not changed, just the 4th and the 5th
It seems like you don't understand for loops that well at all, since this is a pretty simple example. For loops are basically shortcuts in code that iterate through data structures. You can type out for loops line by line, but they would be way longer. In this example,
for (int i = 0; i < 2; i++)
{
primes[4 - i] = primes[i];
}
becomes:
primes[4 - 0] = primes[0];
primes[4 - 1] = primes[1];
So all this loop is doing is setting the last element of the array to the first, and the second-to-last element to the second.
Starting with
int[]primes = {2,3,5,7,11}
the for-loop works like this
i=0 -> primes[4-0] = primes[0]; //array {2,3,5,7,2}
i=1 -> primes[4-1] = primes[1]; //array {2,3,5,3,2}
Imagine you have a zoo(memory) with a row of cages(array) next to each other. each cage is the exact size needed to hold an animal(data type like int)
Zoo---------------------
[animal][animal][animal][animal][animal]
------------------------
You decide to label each cage with a number(index)
Zoo---------------------
[animal][animal][animal][animal][animal]
0 1 2 3 4
------------------------
You get some initial funding to purchase animals for your cages (initialize the array). So you buy a Zebra, Panda, Owl, Tiger, and a Bear and put them in the cages. The order you purchased the animals is the order you place them in their cages.
Zoo---------------------
[Zebra][Panda][Owl][Tiger][Bear]
0 1 2 3 4
------------------------
Your zoo just perfected cloning so you are able to make copies of the animals. You Decide people are really enjoying Pandas & Zebras but don't care for Tigers and Bears. You delegate your tasks(algorithm) by having a sequential stack of index cards with instructions(loop). Each index card has a page number going from 0 up to less than 2, so your last index card has the page number 1
_________________________ ___________________________
|0 | |1 |
| | | |
| | | |
| | | |
| | | |
|_________________________| |___________________________|
You love the number 4 and believe that it is way better then any number and should be the starting point of counting instead of the number 0. So you give all instructions using the number 4 as a reference point.
_____________________________ _____________________________
|0 | |1 |
|Yo zoo keeper, | |Yo zoo keeper, |
|Copy the animal | |Copy the animal |
|in the cage that has this | |in the cage that has this |
|card number and put it in | |card number and put it in |
|cage 4 minus this card number| |cage 4 minus this card number|
|-The Boss | |-The Boss |
|_____________________________| |_____________________________|
Your zoo keeper reads the first index card(with the number 0). He makes a copy of the Zebra and puts in the cage with the Bear. The Zebra immediately eats the bear and is the only inhabitant of the cage.
Zoo---------------------
[Zebra][Panda][Owl][Tiger][Zebra]
0 1 2 3 4
------------------------
Your zoo keeper reads the second index card(with the number 1). He makes a copy of the Panda and puts in the cage with the Tiger. The Panda immediately eats the Tiger and is the only inhabitant of the cage.
Zoo---------------------
[Zebra][Panda][Owl][Panda][Zebra]
0 1 2 3 4
------------------------
And that is how arrays work for primitives. For Objects instead of cages in your zoo you just have a map that points to where you can find the animals in the zoo. Any animal that is not on the list gets marked with a tag and swept to the wild, freeing up space in your zoo.
I have come across the enqueue() method in CircularArrayQueue class:
public void enqueue (T element) {
if (size() == queue.length){
expandCapacity();
}
queue[rear] = element;
rear = (rear+1) % queue.length;
count++;
}
I don't quite understand what the rear = (rear+1) % queue.length; part of the code does, can someone break down the steps of that line of code.
I do understand that it increments rear as a new element has been added however I am unsure of the % operation.
One way to visualize what is happening is to imagine a clock (often used as an analogy for modular arithmetic, which is happening in the line you mentioned with the use of the % operator).
For example, imagine that the CircularArrayQueue has a size of 4 at the moment and that its length is 5 (indices 0 - 4). In the example below, the current value of rear is 4 (index 4)
The items in the internal array might look like this:
INDEX | 0 | 1 | 2 | 3 | 4 |
VALUE | | 8 | 9 | 2 | 1 |
^
|
Rear
Now let's say that you insert the value 7 into the CircularArrayQueue, then the line
rear = (rear + 1) % queue.length;
would be executed. This effectively computes the following:
add 1 to rear (4) -> 5
divide by queue.length (5) -> 5 / 5 = 1 (remainder of 0)
take the remainder of the previous division (0) and set it equal to rear
INDEX | 0 | 1 | 2 | 3 | 4 |
VALUE | 7 | 8 | 9 | 2 | 1 |
^
|
Rear
so after all of these steps, rear now equals 0 and points to the first index in the internal array of the CircularArrayQueue. This behavior of the index "wrapping back around" the array when it reaches the end is the circular behavior that is characteristic of a CircularArrayQueue.
The way that this relates to a clock, is that the minute hand on a clock always "wraps back around" when it reaches 60, and "resets" back to 0.
In other words, the internal array used as an example above, can be thought of as a clock with only 5 minutes (indices 0 - 4). You can think of (rear + 1) as advancing by a minute on the clock. After the "minute hand" (rear) has been incremented 4 times, it starts again at 0.
it basically rounding your queue index for circular queue.
lets say your array queue.length==10,so when rear incremented to 10 it will be rounded to 0 to insert next element at 0 index.
rear = (rear+1) % queue.length; achieves circularity. As CircularArrayQueue class name suggests it is circular. It means that when the last element (queue.length-th) is reached it begins to insert elements from the beginning. rear = (rear+1) % queue.length returns rear+1 in case the rear+1 < queue.length , and 0 if rear+1 == queue.length and in this case it start inserting elements from the beginning of the array.
int firstPosition(int x, int [] a) {
int lower = 0;
int upper = a.length;
while (lower != upper) {
int mid = (lower + upper) / 2;
**if (x <= a[mid]) {** // the line I don't understand
upper = mid;
} else {
lower = mid + 1;
}
return (lower);
}
If a = {4, 4, 5, 5, 6, 7, 8, 9, 9, 9} what will the algorithm return for the following choices of x?
i) x = 3
ii) x = 4
iii) x = 5
iv) x = 9
v) x = 11
I have tried stepping through this program, for example x = 3, a.length returns 10, so upper is always equal to 10.
while ( 3 ! = 0 ) { // execute line
int mid = lower + upper / 2 - which is (0 + 10)/2 = 5
if ( x <= a[mid]) // I assume that means if 3 is less than or equal to 5? 5 then replace mid with 5 and then...
lower = mid + 1 // 5+1 = 6, return 6 as lower?
This is a basic binary search algorithm, implemented iteratively instead of recursively.
The line you don't understand checks to see if x (the search value) might lie in the lower half or upper half of the array. This works because the array is sorted. We can divide any sorted array into two halves, and look at the value in the middle to determine which half the value we're looking for might be in.
Say that the array looks like this:
+---+---+---+---+---+----+
| 1 | 3 | 5 | 7 | 9 | 11 |
+---+---+---+---+---+----+
^ ^
| |
lower upper
and we're trying to figure out which slot the number 9 is in. Since the array is sorted, we can immediately discard half of the array.
How?
Look at the value in the "center" of the array: it's 5, and 9 is larger than 5, so we know that 9 must be in the upper half of the array. Algorithmically speaking, this would be the else case of the if statement in your code.
So we repeat the same process, but only looking at the upper half of the array this time:
+---+---+---+---+---+----+
| 1 | 3 | 5 | 7 | 9 | 11 |
+---+---+---+---+---+----+
^ ^
| |
lower upper
Looks to me like a binary search algorithm. The choice of x makes sure that the array part that needs to be searched is halved each iteration. Read more about it here
This is a modification of a binary search.
Since the data is ordered, to determine if you can throw away the "upper" or "lower" half of a range of data, look at the middle element. When it is bigger than the number you're looking for, you can safely throw away the numbers past it (by reducing the range). When it is smaller than the number you are looking for, you can safely throw away the numbers before it (by reducing the range).
The key here is that if it is the number you are looking for, you need to crawl back towards the beginning of the range until you detect that the "next" number is not actually the "first" of that possibly repeated value.