Recursion to compare two Arrays without using loop [pseudo code] - arrays

Consider the given two arrays A and B without repetitions (that
is, no double occurrences of the same element). The task is to check whether
each element of B is also an element of A without regard to the order.
For instance if A = [1, 2, 3, 4] and B = [2, 3, 1] then the answer is YES. If
however B = [1, 2, 5] then the answer is NO because 5 is not in A.
Design a recursive algorithm (no use of loops) for the above problem.
I am trying to solve the above problem, and there is no way I can find to solve it without using the loop. Would anyone know a way to solve this with recursion without using a loop?
I can not use any builtin functions, this is a recursion exercise for algorithms and data structures.

You can convert a loop to recursion by designing a recursive function/method that operates on a part of your original array (technically on a sub-array) (initially the sub-array will be your complete array) and reducing the size of the array (each time you are passing to your recursive method) by 1.
The following method (I've the implementation in Java) simply checks if the given number is present in the array/list. But notice that it also takes startIndex and endIndex which specifically denotes our boundaries of sub-array/sub-list.
In simple words the following method checks whether the given number is present in list or not but the check is done only between startIndex and endIndex both inclusive. Consider that you pass each element of your array B (listB in my case) to this method, and list argument is actually a reference to your array A (listA in my case).
/**
* This method recursively checks whether given
* number is contained in the given list or not.
*
* For this method startIndex and endIndex
* correspond to the indices of listA
*/
private static boolean contains(List<Integer> list, int startIndex, int endIndex, int number) {
if (startIndex == endIndex) {
return list.get(startIndex) == number;
} else if (startIndex < endIndex) {
return list.get(startIndex) == number || contains(list, startIndex + 1, endIndex, number);
}
// should never be the case
return true;
}
Now, once you have the above method, you can now device a recursive method that pics up all the elements of listB one at a time, and "plugs it in" inside the above method. This can be preciously done as follows:
/**
* This method recurse over each element of listB and checks
* whether the current element is contained in listA or not
*
* for this method startIndex and endIndex correspond to the
* indices of listB
*/
private static boolean contains(List<Integer> listA, List<Integer> listB, int startIndex, int endIndex) {
if (startIndex > endIndex) {
return true;
}
boolean c = contains(listA, 0, listA.size() - 1, listB.get(startIndex));
if (!c) {
return false;
}
return contains(listA, listB, startIndex + 1, endIndex);
}
And a call to above method will look like contains(listA, listB, 0, listB.size() - 1)
Bingo!! You are done.
I'd like you to think of recursive functions in a specific manner. Think of them as like what arguments it take, and what it does. So when you have a recursive call inside the recursive method, you don't need to think how that recursive call will work, rather have an abstraction there and believe that the recursive call will give you the result. Now focus on how you can use this returned result to make this recursive method correctly work.

One way is to turn a simple iterative algorithm -- with a nested loop -- into a recursive one.
An iterative solution, which is not optimised to use a map, but has a O(n²) time complexity, would look like this:
function includesValue(A, v):
for i = 0 to length(A) - 1:
if A[i] == v:
return true
return false
function includesArray(A, B):
for j = 0 to length(B) - 1:
if not includesValue(A, B[j]):
return false
return true
If you translate this into a recursive pattern, you could pass the current index as an extra argument:
function recIncludesValueAfter(A, v, i):
if i >= length(A):
return false
if A[i] == v:
return true
return recIncludesValuesAfter(A, v, i + 1)
function recIncludesSubArray(A, B, j):
if j >= length(B):
return true
if not recIncludesValueAfter(A, B[j], 0):
return false
return recIncludesSubArray(A, B, j + 1)
You would call it with the third argument as 0:
recIncludesSubArray(A, B, 0)
Each of the two recursive functions uses this pattern:
The first if block corresponds to the end of the loop in the iterative version
The second if block corresponds to the body of the for loop in the iterative version (including its potential break-out)
The final recursive call corresponds to the launch of a next iteration in the iterative version.
Optimised by using a Map/Set
If you would need an optimised version, using a set (a map where only the key is important, not the value associated with it), then the iterative version would look like this:
function includesArray(A, B):
setA = new Set
for i = 0 to length(A):
setA.add(A[i])
for j = 0 to length(B) - 1:
if setA.has(B[j]):
return false
return true
Again, we can convert this to a recursive version:
function recAddSubArrayToSet(setA, B, j):
if j >= length(B):
return setA
setA.add(B[j])
return recAddSubArrayToSet(setA, B, j + 1)
function recSetIncludesSubArray(setA, B, j):
if j >= length(B):
return true
if not setA.has(B[j]):
return false
return recSetIncludesSubArray(A, B, j + 1)
function recIncludesSubArray(A, B):
setA = new empty Set
recAddSubArrayToSet(setA, B, 0)
return recSetIncludesSubArray(setA, B, 0)
About built-in functions
You wrote that built-in functions are not allowed. This is a constraint that only makes sense when you have a specific target programming language in mind. In pseudo code there is no concept of built-in functions.
Some languages will provide maps/sets/dictionaries in a way where you can only do something useful with them by calling methods on them (built-in), while other languages will allow you to apply operators (like +) on them, and use an in operator to test membership.
But even getting the size of an array may need a function call in some languages. So this constraint really only makes sense in the context of a specific programming language.

Pseudocode for a function that recursively tests whether the array A contains a given element, x might look something like this:
function isMember(x, A):
if A = [] then return false
if x = A[0] then return true
return isMember(x, A[1..-1])
end
This function is built on the premise that to test if x is a member of A, we can test to see if the first element of A, denoted A[0], is the same as x. If so, we can terminate the function and return true. If not, then call the function again, passing it all the elements of array A except the first one that we already tested. I've denoted the remaining elements of A with A[1..-1], i.e. element numbers 1 through to -1, which in some languages is another way to refer to the last element.
Now during the second call to this function, x is being compared to the first element of A[1..-1], which is, of course, the second element of A. This recurses over and over, each time shrinking the size of array A the element at the top of the list is tested and discarded.
Then we eventually reach the final case, where there are no more elements left in A to test, which results in the final recursive call to the function being passed an empty array. In this situation, we can infer that every element in A failed to match with x, and so we can safely return false, stating the x is not a member of A.
Now, in order to determine whether a given array B is contained by array A, each element in B needs to undergo the test described above. If isMember() returns true for every element in B, then B must be contained by A. If any one element causes isMember() to return false, then we can stop further testing because B contains elements that are not in A, so it cannot be a subarray.
Here's some pseudocode that illustrates this recursive process:
function containedBy(B, A):
if B = [] then return true
let x := B[0]
if not isMember(x, A) then return false
return containedBy(B[1..-1], A)
end
It's very similar in many ways to the first function, which isn't surprising. This time, however, array B is reduced in size with each recursion, as its lead element is passed through to the isMember() function, then discarded upon isMember() returning true. As before, the final case after the last recursive call to containedBy() passes through an empty list in place of B. This can only mean that every element of B successfully passed the membership test with A, so we return true to confirm that B is, indeed, contained by A.

Related

Recursively iterate over an array without changing its size

I am currently trying to solve this problem in Java, but I do not want to set myself onto a specific language since I think of this as a "general" problem.
The conditions for the function I am looking for are:
the only values that can be modified are the values inside the array to be iterated over. Thus, for example, you can not use other variables that store any kind of information, such as indices (which by the way also eliminates the possibility of looping through the array). This also applies to function parameters. The only argument that is passed to the function is the array itself.
additionally to the previous point: memory space must be consistent. Therefore, you cannot copy the current array onto a bigger/smaller array.
However:
the array is an integer array
the function might return an integer value
the elements inside the array might be changed, but only after they are iterated over
the array does not have to be iterated in any kind of order, but every element has to be "reached" exactly once.
there exists a function that returns the length of the array
the signature might look like this (again, no specific language, but since I am currently working in Java, the signature is in Java syntax):
int iterate(int[] integerArray)
Is it possible to write such a function?
One attempt of mine was to traverse the array from index 0 to length(array) - 1, storing the current index at array[0], and exit if array[0] (or array[prev]) is length(array) - 1. So, in order to get the next array element, I would do something like array[array[0]] and increment the counter in array[0]. The major problem with this is that I have to somehow catch the first function call to iterate() in order to initialize array[0] with 0.
This is not a variable but a parameter (the only thing we can work with, otherwise I don't see how it could work), here an example to find max:
function findMax(arr, index = 0, max = Number.MIN_VALUE) {
if (index < arr.length)
return findMax(arr, index + 1, arr[index] > max ? arr[index] : max)
return max
}
console.log(findMax([7,9,2,8,6]))
Or another example with modification, reverse array (without variable for the swap, alternatively you could just write a helper function to do the swapping):
function reverseArray(arr, index = 0, value = arr[0]) {
if (index < arr.length) {
reverseArray(arr, index + 1, arr[index + 1]) // iterate over the whole array
// any modification here will happen after the whole array was iterated
if (index < arr.length / 2) {
arr[index] = arr[arr.length - index - 1]
arr[arr.length - index - 1] = value
}
}
return arr
}
console.log(reverseArray([7,9,2,8,6]))
If you are using a language where you cannot specify predefined values, then you can just overload the method or create a helper, e.g. java:
public int findMax(int[] arr) {
findMax(arr, 0, arr[0]);
}
private int findMax(int[] arr, int i, int max) {
if (i < arr.length)
return findMax(arr, i + 1, arr[i] > max ? arr[i] : max);
return max;
}

Scala - How do I modify an input array passed to a method by reference?

Problem Statement
I will try to elaborate the case by means of a scenario. Lets take this question for instance.
Link to question: https://leetcode.com/problems/remove-element/
Given an array nums and a value target, remove all instances of
that value in-place and return the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
Example: Given nums = [0,1,2,2,3,0,4,2], target = 2; the output =
5 (number of elements not equal to target) and modify the array to
[0,1,3,0,4]
The order of elements can be changed. It doesn't matter what you leave
beyond the new length.
My Approach
Step-1: Identify all the elements which are equal to the given target and move them to right hand side of the array while maintaining a counter.
Step-2: Drop all the elements from right.
Step-3: return (n - counter), where n is the array length and counter is the number of elements equal to target.
Below is the implementation of the same:
object RemoveElement {
// Link to question: https://leetcode.com/problems/remove-element/
def main(args: Array[String]): Unit = {
var nums = Array(3,2,2,3)
val target = 3
val result = removeElement(nums, target)
// nums = nums.dropRight(_.equals(target)) // POINT 1
println(s"Result: ${result}, Modified Array: [${nums.mkString(", ")}]")
}
def removeElement(nums: Array[Int], target: Int): Int = {
val n = nums.length
var left, counter = 0
var right = n - 1
while(left < right){
if(nums(left) != target){
left += 1
}
else {
// Find position of the elements which is not equal to target
if(nums(right) == target){
counter += 1
right -= 1
}
else{
// Swap the elements
counter += 1
val temp = nums(left)
nums(left) = nums(right)
nums(right) = temp
left += 1
right -= 1
}
}
}
// nums.dropWhile(_.equals(target)) // POINT 2
// nums = nums.dropRight(_.equals(target)) // POINT 3
return (n - counter)
}
}
POINT - 1: Makes absolute sense as the array nums is in the scope of main method, therefore, the statement would work as charm.
POINT - 2: These lines has no impact to the array nums.
POINT - 3: Gives error. I understand that the input argument (array nums) is of type val (i.e. passed by reference, and hence immutable within the scope of the method removeElement).
If I had an option of creating a new array, there wouldn't be any issue. But if I am required to return the modified array by adding/removing the elements (like in this question) to the calling method, how do I achieve that in Scala?
To make the case more generic, what is the way by which we can modify the input collections (passed as arguments) in Scala methods?
P.S.: If I do not remove elements from the input array itself, LeetCode fails my submission with below message:
How do I modify an input array passed to a method by reference?
Scala does not support pass-by-reference. The default is pass-by-value (or more precisely, a special case of pass-by-value which is sometimes known as call-by-object, call-by-sharing, or call-by-object-sharing). Scala also supports call-by-name.
So, you simply cannot pass an array to a method by reference in Scala. You will have to use another language which supports pass-by-reference such as C# (with the ref keyword) or C++. (Note that Java also doesn't support pass-by-reference.)
Something like this
object Solution {
def removeElement(nums: Array[Int], `val`: Int): Int = {
var p: Int = 0
nums.foreach(v => {
if (v != `val`) {
nums(p) = v
p += 1
}
})
p
}
}

Converting Function with Two Successive "Tail" Recursive Calls to Iterative Function

I've seen plenty of examples on how to convert a function with a single recursive call at the very end into an iterative version; however, what about when there are two recursive calls right at the end?
Here's an example of what I mean, in Python:
def doit(x, y, L):
if x < y:
x += 1
else:
x -= 1
y -= 1
if y > 0:
L.append(x)
doit(x, y, L)
doit(x - 1, y - 1, L)
#usage
L = []
doit(3, 5, L)
print(L)
Notice that the two recursive calls are right at the very end. Irrespective of whatever I'm doing in the code before those two recursive calls, is there a general method to convert something like this to an iterative version? Remember, what I provided above was just an example.
No, there is no general and simple method for this as there is for tail recursive case. It's true even if you have 1 recursive call at the end but the function isn't tail recursive (e.g return 5+foo(x)). You'll have to explicitly maintain a stack, and then it will work even for cases with more than two recursive calls at the end.
To see why, note that every single variable in a tail-recursive function (meaning parameters and local variables) can have at most one possible value at any given moment. So you never need to maintain more than one version of them in the RAM. Because the moment next recursive call is made, a good compiler will destroy their current version and allocate new version at the same place they are currently in. So it's basically just modifying a variable than allocating new ones.
So for normal recursive functions without that "max 1 version" guarantee, declare a stack before main loop. Every element in it will be a tuple of all parameters. Inside the loop, get stack's last element (& remove it from stack). Then simply copy/paste you function body inside the loop. However, except making next recursive call, create an element containing that call's all parameter values and push it on stack. Your code modified :
A = [] #your initial 'L'
stack = [(2,4,A)] #push values of initial call
while stack:
x,y,L = stack.pop()
print(x,y)
if x < y:
x += 1
else:
x -= 1
y -= 1
if y > 0:
L.append(x)
stack.append((x, y, L))
stack.append((x - 1, y - 1, L))
However, his will work only when order of recursive call doesn't matter, like for dfs. Otherwise, I have an idea for "internal stack" but this answer is already getting too long.

How can I get a boolean out of a reiteration

I made this binary search using reiteration, however, when I get the answer (boolean), I seem to stumble in my way out of the reiteration and cant get the correct answer out of the function.
Can anybody help? Please comment on the code.
// binary search
bool
search(int value, int array[], int n)
{
// the array has more than 1 item
if (n > 1)
{
int m = (n/2);
// compares the middle point to the value
if (value == array [m])
return true;
// if the value given is lower than the middle point of the array
if (value < array [m])
{
int *new_array = malloc (m * sizeof(int));
// creating a new array with the lower half of the original one
memcpy(new_array, array, m * sizeof(int));
// recalling the function
search (value, new_array, m);
}
// if the value given is greater than the middle point of the array
else
{
int *new_array = malloc (m * sizeof(int));
// creating a new array with the upper half of the original one
memcpy(new_array, array + (m + 1), (m * sizeof(int)));
// recalling the function
search (value, new_array, m);
}
}
else if (n==1)
{
// comparing the one item array with the value
if (array[0] == value)
return true;
else
return false;
}
if (true)
return true;
else
return false;
}
You need to return the value of recursive searches.
return search (value, new_array, m);
Otherwise when you call search you are just throwing away the answer
You should return search(...);, and not only invoke the search() method - otherwise the return value is not bubbled up.
In addition, note that this algorithm is O(n) (linear in the size of the array) and is leaking memory and very inefficient, since you copy half of the array in each iteration.
Actually, It probably makes the algorithm much slower then the naive linear search for an element.
A good binary search does not need to copy half of the array - it just "looks" at half of it. It can be achieved by sending array+m as the array (for the higher half), and only decreasing n is enough for the lower half.
As mentioned by amint copying the array completely defeats the purpose of doing a binary search. Second, I believe you mean recursion, not reiteration.
Things to think about: Instead of copying the array, think about how you could achieve the same result by passing in a set of indexes to the array (like beginning and end).
As to your actual question, how to return the boolean value through the recursion. The thing about returning values out of a recursive function is that each iteration has to pass along the value. You can think of it like a chain of responsibility delegation. The first call is like the head of the company. He doesn't do all of the work, so he delegates it to his assistant but he does one piece of the work first. Then the assistant has an assistant etc. Turtles all the way down ;)
In order to get a value back though, each person in the chain has to give it back to the person before them. Going back to programming, this means that every time you recursively call search, you need to return that value.
Lastly, once you have those things in order you need to get your base case better defined. I assume that's what you're trying to do with
if (true)
return true;
else
return false;
However, as pointed out by H2CO3, this doesn't make much sense. In fact, your previous if statement if (n == 1) ... should make sure that the code after that is never executed.

find element in the middle of a stack

I was asked this question in an interview.The problem was i would be given a stack and have to find the element in the middle position of the stack."top" index is not available (so that you don't pop() top/2 times and return the answer).Assume that you will reach the bottom of the stack when pop() returns -1.Don't use any additional data structure.
Eg:
stack index
-----
2 nth element
3
99
.
1 n/2 th element
.
-1 bottom of the stack(0th index)
Answer: 1 (I didn't mean the median.Find the element in middle position)
Is recursion the only way?
Thanks,
psy
Walk through the stack, calculate the depth and on the way back return the appropriate element.
int middle(stack* s, int n, int* depth) {
if (stack_empty(s)) {
*depth = n;
return 0; //return something, doesn't matter..
}
int val = stack_pop(s);
int res = middle(s, n+1, depth);
stack_push(s, val);
if (n == *depth/2)
return val;
return res;
}
int depth;
middle(&stack, 0, &depth);
Note: yes, recursion is the only way. Not knowing the depth of the stack means you have to store those values somewhere.
Recursion is never the only way ;)
However, recursion provides you with an implied additional stack (i.e. function parameters and local variables), and it does appear that you need some additional storage to store traversed elements, in that case it appears that recursion may be the only way given that constraint.
"... Don't use any additional data structure. ..."
Then the task is unsolvable, because you need some place where to store the popped-out data. You need another stack for recursion, which is also a data structure. It doesn't make sense to prohibit any data structure and allow recursion.
Here is one solution: Take two pointers, advance one of them two steps at a time (fast), the other one only one step at a time (slow). If the fast one reaches the bottom return the slow pointer which points to the middle index. No recursion required.
int * slow = stack;
int * fast = stack;
while(1) {
if(STACK_BOTTOM(fast)) return slow;
fast--;
if(STACK_BOTTOM(fast)) return slow;
slow--;
fast--;
}
Recursion seems to be the only way. If you try to use the fast and slow pointer concept during popping, you will need to store the values somewhere and that violates the requirement of no additional data structure.
This question is tagged with c, so for the c programming language I agree that recursion is the only way. However, if first class anonymous functions are supported, you can solve it without recursion. Some pseudo code (using Haskell's lambda syntax):
n = 0
f = \x -> 0 # constant function that always returns 0
while (not stack_empty) do
x = pop
n = n+1
f = \a -> if (a == n) then x else f(a)
middle = f(n/2) # middle of stack
# stack is empty, rebuilt it up to middle if required
for x in (n .. n/2) do push(f(x))
Please note: during the while loop, there's no (recursive) call of f. f(a) in the else branch is just used to construct a new(!) function, which is called f again.
Assumed the stack has 3 elements 10, 20, 30 (from bottom to top) this basically constructs the lambda
(\a -> if a==1
then 30
else (\b -> if b==2
then 20
else (\c -> if c==3
then 10
else (\d -> 0)(c)
)
(b)
)
(a)
)
or a little bit more readable
f(x) = if x==1 then 30 else (if x==2 then 20 else (if x==3 then 10 else 0))

Resources