I have a question about the condition of "entering" the "if condition" in the below recursive binary search:
http://www.fredosaurus.com/notes-cpp/algorithms/searching/rbinarysearch.html
int rBinarySearch(int sortedArray[], int first, int last, int key) {
// function:
// Searches sortedArray[first]..sortedArray[last] for key.
// returns: index of the matching element if it finds key,
// otherwise -(index where it could be inserted)-1.
// parameters:
// sortedArray in array of sorted (ascending) values.
// first, last in lower and upper subscript bounds
// key in value to search for.
// returns:
// index of key, or -insertion_position -1
// if key is not in the array.
if (first <= last) {
int mid = (first + last) / 2; // compute mid point.
if (key == sortedArray[mid])
return mid; // found it.
else if (key < sortedArray[mid])
// Call ourself for the lower part of the array
return rBinarySearch(sortedArray, first, mid-1, key);
else
// Call ourself for the upper part of the array
return rBinarySearch(sortedArray, mid+1, last, key);
}
return -(first + 1); // failed to find key
}
Specifically, I have a question regarding the part if (first <= last).
I was trying to hand trace the step of the above recursion function. For example, I write down an array of say [2, 5, 7, 11, 21, 26, 27, 36, 37, 42] and let the key be 1, i.e. key = 1.
Then I have in the first recursion, I think my first = 0, and last = 9.
So mid = (0 + 9)/2 = 4.5 (but mid will be 4 since mid is assigned to be int).
So mid[4] > 1, so then I have the next recursion being (arr[], 0, 4-1=3, 1),..... and so on.....
However it seems that the case of last < first doesn't seem to appear. I am just wondering is it actually possible for the case of last < first to happen? (i.e.. is the condition if (first <=last) necessary?)
If it is necessary, could someone illustrate with a very simple example that I can hand trace with to understand that this condition is necessary?
thanks
That condition is the stopping criterion for the case if the element that you are looking for is not an element of the array that you are searching.
In your example, if you further exercise it, the recursive calls will be
// first, last
rBinarySearch(arr[], 0, 3, 1); // -> mid = 1 -> else if
rBinarySearch(arr[], 0, 0, 1); // -> mid = 0 -> else if
rBinarySearch(arr[], 0, -1, 1); // there you go: last < first (i.e. -1 < 0)
Related
I have got a code that generates all possible correct strings of balanced brackets. So if the input is n = 4 there should be 4 brackets in the string and thus the answers the code will give are: {}{} and
{{}}.
Now, what I would like to do is print the number of possible strings. For example, for n = 4 the outcome would be 2.
Given my code, is this possible and how would I make that happen?
Just introduce a counter.
// Change prototype to return the counter
int findBalanced(int p,int n,int o,int c)
{
static char str[100];
// The counter
static int count = 0;
if (c == n) {
// Increment it on every printout
count ++;
printf("%s\n", str);
// Just return zero. This is not used anyway and will give
// Correct result for n=0
return 0;
} else {
if (o > c) {
str[p] = ')';
findBalanced(p + 1, n, o, c + 1);
}
if (o < n) {
str[p] = '(';
findBalanced(p + 1, n, o + 1, c);
}
}
// Return it
return count;
}
What you're looking for is the n-th Catalan number. You'll need to implement binomial coefficient to calculate it, but that's pretty much it.
Imagine you're given an unsorted array [5,11,7,4,19,8,11,6,17] and a max weight 23. [similar to Two Sum Problem by a bit different]
One needs to find two optimal weights (by which I mean if two weights that are (almost or not) half of the weight you're trying to find) in this case [5,17], [3,19], [11,11] so I need to return [11,11].
I was taken back by the problem, and could not solve it. [I was not allowed to use structs]
I tried to sort [3, 5, 6, 7, 8, 11, 11, 17, 19] and search from both ends and store indexes of values that were <= max weight in a vector as a pair (like v[i], v[i+1] and check them later by their pairs) then return a pair with both largest vals, but got confused.
[although, weights were doubles and I did not see duplicates at that set I did not use unsorted_map(hashMap), might it've worked?]
Can anyone suggest how should I go about this problem? is it similar to "knapsack problem"? Thank you
You can use Two Pointer Approach for the problem.
Algorithm:
Sort the array.
Have two pointers startIndex and endIndex to 0 and arraySize-1.
sum = arr[startIndex] + arr[endIndex]
If sum is less than or equal to 23, increment startIndex else decrement endIndex.
keep track of closest value using a variable.
finish when startIndex == endIndex
Code in Java:
public class Solution {
private ArrayList<Integer> twoSumClosest(ArrayList<Integer> a, int s) {
// Sort the arraylist
Collections.sort(a);
// closests sum we got till now
int sumClosest = Integer.MIN_VALUE;
// indexes used to traverse
int startIndex = 0;
int endIndex = a.size() - 1 ;
// answer Indexes
int firstIndex = 1;
int secondIndex = a.size() - 1;
while( startIndex < endIndex ) {
if( a.get(startIndex) + a.get(endIndex) > s) {
endIndex--;
continue;
} else {
if( a.get(startIndex) + a.get(endIndex) > sumClosest ) {
sumClosest = a.get(startIndex) + a.get(endIndex);
firstIndex = startIndex;
secondIndex = endIndex;
}
startIndex++;
}
}
ArrayList<Integer> ans = new ArrayList<>();
ans.add(firstIndex);
ans.add(secondIndex);
return ans;
}
}
Time Complexity: O(nlogn)
O(n) if array was already sorted
Extra Space Needed: O(1)
I have a function evaluate that takes arguments. The first argument is an Int. The second argument of a closure that takes an Int and returns a Double. The function evaluate then returns a [Double]. The k’th element of the returned array is the result of evaluating the second argument with the value k for k = 0, 1, ..., n.
func evaluate(n: Int, myFunction: Int -> Double) -> [Double] {
var doubles = [Double]()
for i in 1...n {
doubles[i] = myFunction(i)
}
return doubles
}
let polyTableClosure: Int -> Double = { return Double($0 * $0 * $0 + 2 * $0 + 4) }
print(evaluate(5, polyTableClosure))
Expecting something like: [7, 16, 37, 76, 139]
The myFunction: label is missing. Your call of evaluate should be:
evaluate(5, myFunction: polyTableClosure)
Also, accessing an empty array at index i will not create a new slot at that index. It will fail.
You must append to the array:
for i in 1...n {
doubles.append(myFunction(i))
}
I am a novice at OpenCL and recently I have stumbled onto something which does not make sense to me.
I am using Intel drivers (working on linux machine) and the device is Xeon Phi coprocessor.
The problem is that when I give local_item_size as an argument to
clEnqueueNDRangeKernel(commandQueue,
forceKernel, 1,
&localItemSize, &globalItemSize,
NULL, 0, NULL, &kernelDone);
and when printing global thread id in the kernel
int tid = get_global_id(0);
The thread ids start from 1 and not from 0.
When I do not describe what my local_item_size and have NULL as an argument it seems to start counting correctly from 0.
At the moment I am fixing this in my code by subtracting 1 from the return value of get_global_id(0) for my code to work correctly..
Shortly: When I say what my local_item_size is the tid starts from 1. When I give NULL it starts from 0.
Size setting code:
// Global item size
if (n <= NUM_THREADS) {
globalItemSize = NUM_THREADS;
localItemSize = 16;
} else if (n % NUM_THREADS != 0) {
globalItemSize = (n / NUM_THREADS + 1) * NUM_THREADS;
} else {
globalItemSize = n;
}
// Local item size
localItemSize = globalItemSize / NUM_THREADS;
The 4th parameter to clEnqueueNDRangeKernel is an array of the offsets, not the local size - that's the 6th parameter. Your call should be
clEnqueueNDRangeKernel(commandQueue,
forceKernel, 1,
NULL, &globalItemSize,
&localItemSize, 0, NULL, &kernelDone);
This is also why the IDs started at 1 - because you requested an offset of 1!
You are passing your work-group size to the wrong argument. The third argument of clEnqueueNDRangeKernel is the global work offset, which is why your global IDs are appearing offset. The work-group size should go to the sixth argument:
clEnqueueNDRangeKernel(commandQueue,
forceKernel, 1, NULL,
&globalItemSize, &localItemSize,
0, NULL, &kernelDone);
I am just trying to understand how the recursion works in this example, and would appreciate it if somebody could break this down for me. I have the following algorithm which basically returns the maximum element in an array:
int MaximumElement(int array[], int index, int n)
{
int maxval1, maxval2;
if ( n==1 ) return array[index];
maxval1 = MaximumElement(array, index, n/2);
maxval2 = MaximumElement(array, index+(n/2), n-(n/2));
if (maxval1 > maxval2)
return maxval1;
else
return maxval2;
}
I am not able to understand how the recursive calls work here. Does the first recursive call always get executed when the second call is being made? I really appreciate it if someone could please explain this to me. Many thanks!
Code comments embedded:
// the names index and n are misleading, it would be better if we named it:
// startIndex and rangeToCheck
int MaximumElement(int array[], int startIndex, int rangeToCheck)
{
int maxval1, maxval2;
// when the range to check is only one cell - return it as the maximum
// that's the base-case of the recursion
if ( rangeToCheck==1 ) return array[startIndex];
// "divide" by checking the range between the index and the first "half" of the range
System.out.println("index = "+startIndex+"; rangeToCheck/2 = " + rangeToCheck/2);
maxval1 = MaximumElement(array, startIndex, rangeToCheck/2);
// check the second "half" of the range
System.out.println("index = "+startIndex+"; rangeToCheck-(rangeToCheck/2 = " + (rangeToCheck-(rangeToCheck/2)));
maxval2 = MaximumElement(array, startIndex+(rangeToCheck/2), rangeToCheck-(rangeToCheck/2));
// and now "Conquer" - compare the 2 "local maximums" that we got from the last step
// and return the bigger one
if (maxval1 > maxval2)
return maxval1;
else
return maxval2;
}
Example of usage:
int[] arr = {5,3,4,8,7,2};
int big = MaximumElement(arr,0,arr.length-1);
System.out.println("big = " + big);
OUTPUT:
index = 0; rangeToCheck/2 = 2
index = 0; rangeToCheck/2 = 1
index = 0; rangeToCheck-(rangeToCheck/2 = 1
index = 0; rangeToCheck-(rangeToCheck/2 = 3
index = 2; rangeToCheck/2 = 1
index = 2; rangeToCheck-(rangeToCheck/2 = 2
index = 3; rangeToCheck/2 = 1
index = 3; rangeToCheck-(rangeToCheck/2 = 1
big = 8
What is happening here is that both recursive calls are being made, one after another. The first one searches have the array and returns the max, the second searches the other half and returns the max. Then the two maxes are compared and the bigger max is returned.
Yes. What you have guessed is right. Out of the two recursive calls MaximumElement(array, index, n/2) and MaximumElement(array, index+(n/2), n-(n/2)), the first call is repeatedly carried out until the call is made with a single element of the array. Then the two elements are compared and the largest is returned. Then this comparison process is continued until the largest element is returned.