Recursively iterate over an array without changing its size - arrays

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;
}

Related

Checking If Array Is Ascending Using Recursion

I have learned recursion just recently and I was met with a question that I HAVE to approach it using recursion which says something like this, I need a function that takes an array and it's size using user input and checks if the array is ascending and if it is it returns 1 and if not it returns 0, now I know doing it without recursion is way easier but I had to do it with recursion, i tried different approaches to my base case and my if-else conditions and it didn't work out well I tried something like Array[Index] >= Array[Index-1] , and tried some other stuff alongside , but for some reason it just won't work and keeps giving me that it's descending
Here is what I tried: I have my main in which user inputs array and size(aka index here) and then calling this recursive function to try and see if it's ascending, now I assumed I'm starting from the most left of the array and go down gradually and check but it doesn't work, anyone got some tips on what's happening here?
int CheckIfAscending(int* Array, int Index)
{
if (Index < 0)
{
return 1;
}
if (Array[Index] > Array[Index - 1])
{
return CheckIfAscending(Array, Index - 1);
}
if (Array[Index] < Array[Index - 1])
{
return 0;
}
}
The most obvious vulnerability of your code is the lack of defined behaviour for arrays which can have the same value occur in two consecutive entries.
Because what do you return in case Array[Index] == Array[Index - 1]?
Your code does not specify, it does not have any return statement for that case.
You need to decide whether you want strictly ascending, i.e. two identical values are a failure, or only ascending, i.e. they are fine.
For strictly ascending do this
if (Array[Index] > Array[Index - 1])
{
return CheckIfAscending(Array, Index - 1);
} else
{
return 0;
}
otherwise use >=.
You also need to fix the first condition if (Index < 0), because for index 0 (actually size I think...) you need to already answer directly, otherwise Index - 1 is meaningless. So, use Index <= 0 instead.

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
}
}

Applying a function on sorted array

Taken from the google interview question here
Suppose that you have a sorted array of integers (positive or negative). You want to apply a function of the form f(x) = a * x^2 + b * x + c to each element x of the array such that the resulting array is still sorted. Implement this in Java or C++. The input are the initial sorted array and the function parameters (a, b and c).
Do you think we can do it in-place with less than O(n log(n)) time where n is the array size (e.g. apply a function to each element of an array, after that sort the array)?
I think this can be done in linear time. Because the function is quadratic it will form a parabola, ie the values decrease (assuming a positive value for 'a') down to some minimum point and then after that will increase. So the algorithm should iterate over the sorted values until we reach/pass the minimum point of the function (which can be determined by a simple differentiation) and then for each value after the minimum it should just walk backward through the earlier values looking for the correct place to insert that value. Using a linked list would allow items to be moved around in-place.
The quadratic transform can cause part of the values to "fold" over the others. You will have to reverse their order, which can easily be done in-place, but then you will need to merge the two sequences.
In-place merge in linear time is possible, but this is a difficult process, normally out of the scope of an interview question (unless for a Teacher's position in Algorithmics).
Have a look at this solution: http://www.akira.ruc.dk/~keld/teaching/algoritmedesign_f04/Artikler/04/Huang88.pdf
I guess that the main idea is to reserve a part of the array where you allow swaps that scramble the data it contains. You use it to perform partial merges on the rest of the array and in the end you sort back the data. (The merging buffer must be small enough that it doesn't take more than O(N) to sort it.)
If a is > 0, then a minimum occurs at x = -b/(2a), and values will be copied to the output array in forward order from [0] to [n-1]. If a < 0, then a maximum occurs at x = -b/(2a) and values will be copied to the output array in reverse order from [n-1] to [0]. (If a == 0, then if b > 0, do a forward copy, if b < 0, do a reverse copy, If a == b == 0, nothing needs to be done). I think the sorted array can be binary searched for the closest value to -b/(2a) in O(log2(n)) (otherwise it's O(n)). Then this value is copied to the output array and the values before (decrementing index or pointer) and after (incrementing index or pointer) are merged into the output array, taking O(n) time.
static void sortArray(int arr[], int n, int A, int B, int C)
{
// Apply equation on all elements
for (int i = 0; i < n; i++)
arr[i] = A*arr[i]*arr[i] + B*arr[i] + C;
// Find maximum element in resultant array
int index=-1;
int maximum = -999999;
for (int i = 0; i< n; i++)
{
if (maximum < arr[i])
{
index = i;
maximum = arr[i];
}
}
// Use maximum element as a break point
// and merge both subarrays usin simple
// merge function of merge sort
int i = 0, j = n-1;
int[] new_arr = new int[n];
int k = 0;
while (i < index && j > index)
{
if (arr[i] < arr[j])
new_arr[k++] = arr[i++];
else
new_arr[k++] = arr[j--];
}
// Merge remaining elements
while (i < index)
new_arr[k++] = arr[i++];
while (j > index)
new_arr[k++] = arr[j--];
new_arr[n-1] = maximum;
// Modify original array
for (int p = 0; p < n ; p++)
arr[p] = new_arr[p];
}

Strange expression in the return statement

I found a recursive function that left me a little surprised this function counts all negative numbers which appear in an array :
int count_negative(int arr[], int n)
{
if ( n > 0 )
return (*arr < 0) + count_negative( ++arr, n - 1 );
return 0;
}
Can someone explain this line :
return (*arr < 0) + count_negative( ++arr, n-1 );
Thank you
(*arr < 0) compares first element of the array with zero. The result of the expression can be either 1 (first element is negative) or 0 (first element is positive or zero). So, the number of negative elements is the sum of this expression and the number of negative elements in the tail of the array.
*arr points to the first element of arr array (or, more precisely, the part of the arr that has been passed to the function in this particular call).
count_negative( ++arr, n-1 ) is a recursive call but because of ++arr, inside this call we count the next element of the array and n-1 argument, togeher with the if ( n > 0 ) guarantees that we will count only elements inside the arr array.
The principle is that instead of keeping an index on the element being inspected, since arr is a pointer and modifying it will not change the data, one may instead use arr itself as the iterator on the array data.
So, *arr < 0 checks if the current pointed element is negative (it will yield 1 if so, 0 if not), and ++arr increments the cursor to the next place in the array, which is then passed on recursively to check the rest of the array.
This is a very well known idea in functional languages working with lists, where you often work on the first element of the list (the head) and recurse on the remaining of the list (the tail).

AS3 am i using array.slice() currently?

I want to remove a value from a array, at a set index.
this is the while loop i have
while (i < objects.length)
{
var index:int = get_index(objects[i]);
if (index != -1)
{
Quadtree_list[index].insert(objects[i]);
objects.slice(i, 1);
} else {
i++;
}
}
sooner or later i cannot get out the loop, so it crashes
but if i replace objects.slice with object.pop, it works (but its not removing the right index)
quick note objects.slice(i, 1) is not reducing the length of the array but objects.pop() is, how do i make .slice() reduce the size of the array?.
Array.slice(x,y) returns an Array containing the elements from index x to index y.
I believe what you're after is Array.splice(startIndex, deleteCount), this is a multi-purpose function. In your code objects.splice(i, 1);
Starting from index (startIndex)
Remove elements up to deleteCount (1)
return an Array containing removed elements

Resources