Recursive binary search errors in c++ - c++

I'm trying to write a recursive binary search function using below approach. I'm basically using divide and conquer strategy and everything looks good to me in code, but unable to figure out where my code and approach goes wrong.
#include<iostream>
using namespace std;
bool b_search(int *arr, int n, int start, int end){
if(start==end){
if(arr[start]==n){
return true;
}
else{
return false;
}
}
else{
int mid=start+(end-start)/2;
if(arr[mid]==n){
return true;
}
else if(arr[mid]>n){
return b_search(arr,n,mid+1,end);
}
else{
return b_search(arr,n,start,mid-1);
}
}
}
int main(){
int arr[8]={3,5,8,11,13,15,16,25};
cout<<b_search(arr,16,0,7);
}
I'm getting output as zero but it should be 1.

When arr[mid]>n you then search for the number in the part with higher number which is guaranteed to miss. You need to search in the part with lower numbers.
Example:
bool b_search(int *arr, int n, int start, int end) {
if (start == end) return arr[start] == n;
int mid = start + (end - start) / 2;
if (arr[mid] < n) { // arr[mid] is lower than n, search in the high part
return b_search(arr, n, mid + 1, end);
} else if (arr[mid] > n) { // arr[mid] is greater than n, search lower part
return b_search(arr, n, start, mid - 1);
}
return true;
}

Your next interval is wrong.
else if(arr[mid]>n){
return b_search(arr,n,mid+1,end);
When the middle element is too large then you continue with the larger portion of the array. You should continue with the smaller portion of the array instead:
else if(arr[mid]<n){
return b_search(arr,n,mid+1,end);
}
else{
return b_search(arr,n,start,mid-1);
}

You are searching in the wrong direction. If arr[mid] > n then you should be searching from start to mid -1 and the other way around. The reason is that your searched value n is then in the other half of your searched array
#include<iostream>
using namespace std;
bool b_search(int *arr, int n, int start, int end)
{
if(start==end)
{
if(arr[start]==n)
{
return true;
}
else
{
return false;
}
}
else
{
int mid=start+(end-start)/2;
if(arr[mid]==n)
{
return true;
}
else if(arr[mid]<n) // turn around the comparison
{
return b_search(arr,n,mid+1,end);
}
else
{
return b_search(arr,n,start,mid-1);
}
}
}
int main()
{
int arr[8]={3,5,8,11,13,15,16,25};
cout<<b_search(arr,16,0,7);
}

Related

Error while counting all possible paths from top left to bottom right of a m x n matrix

This is the logic I came up with, but I am getting SIGSEGV error. and I don't know why it is happening.
#include <bits/stdc++.h>
using namespace std;
int path(int m, int n,int dist[1000][1000]) {
if(dist[m][n]!=-1) {
return dist[m][n];
}
else if(m==1 && n==1) {
return 1;
}
else if(m==0 || n==0) {
return 0;
}
dist[m][n]=path(m-1,n,dist)+path(m,n-1,dist);
return dist[m][n];
}
int main() {
// your code goes here
int dist[1000][1000];
memset(dist, -1, sizeof(dist)*1000*1000);
int s=path(3,3,dist);
return 0;
}

Function does not return value when it should

I wrote the following code for binary search
int binarySearch(int input[], int start, int end, int element) {
if(start<=end) {
int mid = (start+end)/2;
if(input[mid]==element) {
cout<<"mid will be returned\n";
return mid;
}
else if(input[mid]<element) {
binarySearch(input, mid+1, end, element);
} else if (input[mid]>element) {
binarySearch(input, start, mid-1, element);
}
}
return -1;
}
Now, for the input
10 //size of array
1 2 3 4 5 6 7 8 9 10 //array
1 //element to be found
I get the output
mid will be returned
-1
But if I put an else before return -1(in the second last line), it works just fine and returns
mid will be returned
0
The question is, shouldn't the function just return mid = 0 in the first case and return 0?
Here's the main function for your reference:
int main() {
int input[100000],length,element, ans;
cin >> length;
for(int i =0;i<length;i++)
{
cin >> input[i];;
}
cin>>element;
ans = binarySearch(input, 0, length-1, element);
cout<< ans << endl;
}
You have to put a return before your recursive calls
int binarySearch(int input[], int start, int end, int element) {
if(start<=end) {
int mid = (start+end)/2;
if(input[mid]==element) {
cout<<"mid will be returned\n";
return mid;
}
else if(input[mid]<element) {
return binarySearch(input, mid+1, end, element); // here
} else if (input[mid]>element) {
return binarySearch(input, start, mid-1, element); // here
}
}
return -1;
}
Add return on where you calling again the function. Return will return the value to the caller function so each recursive will return the value to its caller function. So your code should be,
int binarySearch(int input[], int start, int end, int element) {
if(start<=end) {
int mid = (start+end)/2;
if(input[mid]==element) {
cout<<"mid will be returned\n";
return mid;
}
else if(input[mid]<element) {
return binarySearch(input, mid+1, end, element);
} else if (input[mid]>element) {
return binarySearch(input, start, mid-1, element);
}
}
return -1;
}
Your code seems correct except the fact you don't return the result of binarySearch in recursive function.
So that gets executed but the result is not used by the original (top level) binarySearch call.
To make the main program get the right value of binarySearch method, it should call itself each time.
Change this part and try again:
else if(input[mid]<element) {
return binarySearch(input, mid+1, end, element);
} else if (input[mid]>element) {
return binarySearch(input, start, mid-1, element);
}

Unsure about the time complexity

So I was doing a question on LeetCode...
Question:
Write an efficient algorithm that searches for a target value in an m x n integer matrix. The matrix has the following properties:
Integers in each row are sorted in ascending from left to right.
Integers in each column are sorted in ascending from top to bottom.
Example 1:
Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
Output: true
Example 2:
Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
Output: false
So first I attempted this question by regular brute force method:
Answer-1:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int t) {
int i=0,j,I=matrix.size(),J,mj;
for(;i<I;i++)
{
j=0;J=matrix[i].size()-1;
mj=(j+J)/2;
while(j<=J)
{
if(matrix[i][mj]==t)
return true;
else if(matrix[i][mj]<t)
j=mj+1;
else
J=mj-1;
mj=(j+J)/2;
}
}
return false;
}
};
Then I decided to do it by idk Divide and Conquer ig...
Answer-2:
class Solution {
public:
bool VFinder(vector<vector<int>>& matrix, int hstart, int hend, int vstart, int vend, int ele)
{
if(vstart > vend || hstart > hend)
return false;
int mid = vstart;
int start = vstart;
int end = vend;
while(start<=end)
{
mid = (int)((start + end) / 2);
if (start == end)
{
if (matrix[mid][hstart] == ele)
{
return true;
}
else
{
return HFinder(matrix, hstart + 1, hend, vstart, mid, ele);
}
}
else
{if(matrix[mid][hstart] <ele && matrix[mid+1][hstart] > ele)
return HFinder(matrix, hstart+1, hend, vstart, mid,ele);
else if(matrix[mid][hstart] <ele)
start = mid+1;
else if(matrix[mid][hstart] >ele)
end = mid-1;
else if(matrix[mid][hstart] == ele)
return true;}
}
return false;
}
bool HFinder(vector<vector<int>>& matrix, int hstart, int hend, int vstart, int vend, int ele)
{
if(hstart > hend || vstart > vend)
return false;
int mid = hstart;
int start = hstart;
int end = hend;
while(start<=end)
{
mid = (int)((start + end) / 2);
if (start == end)
{
if (matrix[vstart][mid] == ele)
{
return true;
}
else
{
return VFinder(matrix, hstart, mid, vstart + 1, vend, ele);
}
}
else
{if(matrix[vstart][mid] <ele && matrix[vstart][mid+1] > ele)
return VFinder(matrix, hstart, mid, vstart+1, vend, ele);
else if(matrix[vstart][mid] <ele)
start = mid+1;
else if(matrix[vstart][mid] >ele)
end = mid-1;
else if(matrix[vstart][mid] == ele)
return true;}
}
return false;
}
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int horizontal = matrix[0].size();
int vertical = matrix.size();
return HFinder(matrix, 0, horizontal-1, 0, vertical-1, target);
}
};
So the first code after submission took about : 328 ms
And the second one took about : 488 ms
But in second one, I am after each step reducing the search space, so it should have taken less time as compared to the first code, but it is not happening so.
Can someone please tell me why is it so?
And also what is the time complexity of the second code?

Difference between returning a function and calling a function in recursion

Here is a simple code of Binary Search in C++:
int binarySearch(vector<int> &vec, int start, int end, int element) {
int middle = 0;
if (start <= end) {
middle = start + (end - start) / 2;
if (vec[middle] == element) {
return middle;
}
else if (vec[middle] < element) {
binarySearch(vec, middle + 1, end, element);
}
else {
binarySearch(vec, start, middle - 1, element);
}
}
return -1;
}
It always produces the result -1. Now, I know that in a function's stack unwinding phase, the last return -1 gets called.
However, the following code works just fine:
int binarySearch(vector<int> &vec, int start, int end, int element) {
int middle = 0;
if (start <= end) {
middle = start + (end - start) / 2;
if (vec[middle] == element) {
return middle;
}
else if (vec[middle] < element) {
return binarySearch(vec, middle + 1, end, element);
}
else {
return binarySearch(vec, start, middle - 1, element);
}
}
return -1;
}
I want to know what exactly is the difference between returning a function and calling a function?

Find binary tree height

I am trying to write a function to get the height of a binary tree. When I print the value of the maxi the value is what I expect but when the function returns the value, the value is always 0. Can someone tell what I am doing wrong here?
int treeHeight(tree *p)
{
static int maxi=0;
static int i=0;
if(p==NULL)
{
return maxi;
}
else
{
if(p->left!=NULL||p->right!=NULL)
{
i++;
}
else
{
i++;
if(maxi<i)
{
maxi=i;
}
}
treeHeight(p->left);
treeHeight(p->right);
i--;
}
}
Your treeHeight function should look like the following:
int treeHeight(tree *p)
{
if (p == NULL)
{
return -1;
}
int left = treeHeight(p->left);
int right = treeHeight(p->right);
return 1 + std::max(left, right);
}
Why do you need to static variables i and maxi there? You don't need those variables there to find out the height of a binary tree.