1. balance speed and accuracy
(think twice before start, think if there is a better data structure)
2. do not be overwhelmed by stl
especially those i am not familiar with.
3. make ur program as simple as possible. if for loop is too complicated, use while. if need temp variable, then use it, if need to start with a big complexity, then do it. improve it little by little. (simplicity avoid corner case)
4. it is more important to keep clear logic rather than rushing fast.
Thursday, February 28, 2013
some classical problems
1. divide and conquer
see: http://www.cse.ust.hk/faculty/scheng/comp3711h/notes/array.pdf
can also use our method of BST.
both nlogn
2. closest pair
divide and conquer
3. minimum spanning tree:
prim's algorithm
kruskal algorithm
Dijkstra’s algorithm and prim's algorithm
skyline problem: divide and conquer == search + bst
see: http://www.cse.ust.hk/faculty/scheng/comp3711h/notes/array.pdf
can also use our method of BST.
both nlogn
2. closest pair
divide and conquer
3. minimum spanning tree:
prim's algorithm
kruskal algorithm
Dijkstra’s algorithm and prim's algorithm
skyline problem: divide and conquer == search + bst
Teris problem
http://www.careercup.com/question?id=14099679
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
typedef map<int,int> Map;
Map FindOverNth(int arr[],int size,int n)
{
Map ret_map;
typedef Map::value_type Elem;
int total=0;
for_each(arr,arr+size,[&,n](int val)
{
auto ret_pair=ret_map.insert(Elem(val,0)); //no duplicates!
++(*ret_pair.first).second;++total;
if(ret_map.size()==n)
{
for(auto iter=ret_map.begin();iter!=ret_map.end();)
{
--(*iter).second;
--total;
if((*iter).second==0)
ret_map.erase(iter++);
else
iter++;
}
}
});
for_each(ret_map.begin(),ret_map.end(),[](Elem &elem){elem.second=0;});
for_each(arr,arr+size,[&ret_map](int val){if(ret_map.find(val)!=ret_map.end())ret_map[val]++;});
for(auto iter=ret_map.begin();iter!=ret_map.end();)
{
if((*iter).second<=size/n)
ret_map.erase(iter++);
else
iter++;
}
return ret_map;
}
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
typedef map<int,int> Map;
Map FindOverNth(int arr[],int size,int n)
{
Map ret_map;
typedef Map::value_type Elem;
int total=0;
for_each(arr,arr+size,[&,n](int val)
{
auto ret_pair=ret_map.insert(Elem(val,0)); //no duplicates!
++(*ret_pair.first).second;++total;
if(ret_map.size()==n)
{
for(auto iter=ret_map.begin();iter!=ret_map.end();)
{
--(*iter).second;
--total;
if((*iter).second==0)
ret_map.erase(iter++);
else
iter++;
}
}
});
for_each(ret_map.begin(),ret_map.end(),[](Elem &elem){elem.second=0;});
for_each(arr,arr+size,[&ret_map](int val){if(ret_map.find(val)!=ret_map.end())ret_map[val]++;});
for(auto iter=ret_map.begin();iter!=ret_map.end();)
{
if((*iter).second<=size/n)
ret_map.erase(iter++);
else
iter++;
}
return ret_map;
}
Wednesday, February 27, 2013
random access of stl
set<int>::iterator iter=test.end();
iter=iter-1; //not allowed!!
iter--; //allowed
deque...
iter=iter-1;//allowed
list...
iter=iter-1;//not allowed!
iter--;//allowed
iter=iter-1; //not allowed!!
iter--; //allowed
deque...
iter=iter-1;//allowed
list...
iter=iter-1;//not allowed!
iter--;//allowed
Tuesday, February 26, 2013
string matching
void preMap(char *x,int m,int mpNext[])
{
int i,j;
i=0;
j=mpNext[0]=-1;
while(i<m)
{
while(j>-1 && x[i]!=x[j])
j=mpNext[j];
mpNext[++i]=++j;
}
}
void MP(char *x,int m,char* y,int n)
{
int i,j,mpNext[256];
preMap(x,m,mpNext);
i=j=0;
while(j<n)
{
while(i>-1 && x[i]!=y[j])
i=mpNext[i];
i++;
j++;
if(i>=m)
{
cout<<x<<endl;
i=mpNext[i];
}
}
}
C++ revisited
1. const and reference members may only be initialized, never assigned.
2. list members in an initialization list in order in which they are declared.
- static data members are initialized only once.
- base class data members are initialized before derived class data members.
-virtual destructor must be defined
3. ps1->Shape::draw(); //explicitly call base function
4. a summary of public/private inheritance and friend:
- public and private inheritance can access public and protected members of base class;
- public and private inheritance cant access private members of base class;
- an instance of derived class
--public inheritance can access public members of base class
--private inheritance cannot access public members of base class
class B
{
friend class A;
friend B operator+(B b1, B b2);
}
A can access private members of B;
+ can access private members of B;
2. list members in an initialization list in order in which they are declared.
- static data members are initialized only once.
- base class data members are initialized before derived class data members.
-virtual destructor must be defined
3. ps1->Shape::draw(); //explicitly call base function
4. a summary of public/private inheritance and friend:
- public and private inheritance can access public and protected members of base class;
- public and private inheritance cant access private members of base class;
- an instance of derived class
--public inheritance can access public members of base class
--private inheritance cannot access public members of base class
class B
{
friend class A;
friend B operator+(B b1, B b2);
}
A can access private members of B;
+ can access private members of B;
Monday, February 25, 2013
a very interesting problem
if you see O(n). dont hesitate just do linear traversal
http://www.careercup.com/question?id=14912744
void PrintReverse(int i,int j)
{
for(int k=j;k>=i;k--)
cout<<k<<endl;
}
void WritePermu(string signature)
{
int N=signature.length();
int lasti=1;
for(int i=0;i<N;i++)
{
if(signature[i]=='I')
{
PrintReverse(lasti,i+1);
lasti=i+2;
}
}
PrintReverse(lasti,N+1);
}
it can also be solved using topological sort
http://www.careercup.com/question?id=14912744
void PrintReverse(int i,int j)
{
for(int k=j;k>=i;k--)
cout<<k<<endl;
}
void WritePermu(string signature)
{
int N=signature.length();
int lasti=1;
for(int i=0;i<N;i++)
{
if(signature[i]=='I')
{
PrintReverse(lasti,i+1);
lasti=i+2;
}
}
PrintReverse(lasti,N+1);
}
it can also be solved using topological sort
tree bfs
void FindNode(Node* root)
{
deque<Node*> queue1,queue2;
queue1.push_back(root);
int level=0;
Node* last_node=root;
while(!queue1.empty() || !queue2.empty())
{
if(!queue1.empty())
{
Node* cur_node=queue1.front();
last_node=cur_node;
if(cur_node->L)
queue2.push_back(cur_node->L);
else if(cur_node->R)
queue2.push_back(cur_node->R);
queue1.pop_front();
}
if(!queue2.empty())
{
Node* cur_node=queue2.front();
last_node=cur_node;
if(cur_node->L)
queue1.push_back(cur_node->L);
else if(cur_node->R)
queue1.push_back(cur_node->R);
queue2.pop_front();
}
level++;
}
cout<<last_node->val<<endl;
}
Sunday, February 24, 2013
backtracking using stack/deque
void GetSentence(string text,vector<string> dictionary)
{
deque<pair<string,int>> my_deque;
hash_set<string> my_hash;
int N=dictionary.size();
vector<int> temp(text.length());
fill(temp.begin(),temp.end(),-1);
for(int i=0;i<N;i++)
my_hash.insert(dictionary[i]);
my_deque.push_back(pair<string,int>::pair("",-1));
while(!my_deque.empty())
{
pair<string,int> top_string=my_deque.back();
int cur_pos=top_string.second;
if(cur_pos==text.length()-1)
break;
bool flag=false;
for(int i=cur_pos+1;i<text.length();i++)
{
string sub_string=text.substr(cur_pos+1,i-cur_pos);
hash_set<string>::iterator iter=my_hash.find(sub_string);
if(iter!=my_hash.end() && i>temp[cur_pos+1])
{
my_deque.push_back(pair<string,int>::pair(sub_string,i));
temp[cur_pos+1]=i;
flag=true;
break;
}
}
if(!flag)
my_deque.pop_back();
}
if(!my_deque.empty())
my_deque.pop_front();
while(!my_deque.empty())
{
pair<string,int> cur_pair=my_deque.front();
my_deque.pop_front();
cout<<cur_pair.first<<" ";
}
cout<<endl;
}
tree post order traversal using stack
int GetDiameter2(int& height)
{
if(!root)return 0;
stack<Node*> s;
s.push(root);
Node* prev=NULL;
int res=0;
while(!s.empty())
{
Node* cur=s.top();
if(!prev || prev->L==cur || prev->R==cur)
{
if(cur->L)
s.push(cur->L);
else if(cur->R)
s.push(cur->R);
else
{
s.pop();
cur->tmp=1;
res=max(res,1);
}
}
else if(cur->L==prev)
{
if(cur->R)
s.push(cur->R);
else
{
s.pop();
cur->tmp=cur->L->tmp+1;
res=max(res,cur->L->tmp+1);
}
}
else if(cur->R==prev)
{
s.pop();
if(cur->L)
{
cur->tmp=max(cur->L->tmp,cur->R->tmp)+1;
res=max(res,cur->L->tmp+cur->R->tmp+1);
}
else
{
cur->tmp=cur->R->tmp+1;
res=max(res,cur->R->tmp+1);
}
}
prev=cur;
}
return res;
}
check overlapping
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool MyCompare(pair<int,int> p1,pair<int,int> p2){return p1.first<p2.first;}
bool MyCompare2(int p1,pair<int,int> p2){return p1<p2.first;}
int NumOfIntersection(vector<int> A)
{
int N=A.size();
vector<pair<int,int>> P;
for(int i=0;i<N;i++)
{
int start_pt=i-A[i],end_pt=i+A[i];
P.push_back(pair<int,int>::pair(start_pt,end_pt));
}
sort(P.begin(),P.end(),MyCompare);
int res=0;
for(int i=0;i<N;i++)
{
vector<pair<int,int>>::iterator iter=upper_bound(P.begin()+i,P.end(),P[i].second,MyCompare2);
iter--;
int id=iter-P.begin();
res+=(id-i);
}
return res;
}
Saturday, February 23, 2013
sum range (a lot of stl!!)
find the range that sum up to a closest value to a given value
#include<set>
#include<vector>
#include<algorithm>
#include<iostream>
#include<iterator>
using namespace std;
struct ltstr
{
bool operator()(pair<int,int> p1, pair<int,int> p2) const
{
return p1.first<p2.first;
}
};
void FindRange(vector<int> X,int val,int& startId, int& endId)
{
int size=X.size();
//preprocessing sum
set<pair<int,int>,ltstr> sum;
vector<pair<int,int>> my_vec;
int cur_sum=0;
for(int i=0;i<=size;i++)
{
sum.insert(pair<int,int>::pair(cur_sum,i));
my_vec.push_back(pair<int,int>::pair(cur_sum,i));
if(i<size)cur_sum+=X[i];
}
int closest=INT_MAX;
for(vector<pair<int,int>>::iterator iter=my_vec.begin();iter!=(my_vec.end()-1);iter++)
{
//remove already searched range so the output range is valid
pair<int,int> to_erase=*iter;
sum.erase(*iter);
int to_search=(*iter).first+val;
//search for closest value with lower bound and upper bound
set<pair<int,int>,ltstr>::iterator lower_bound=sum.lower_bound(pair<int,int>::pair(to_search,0));
set<pair<int,int>,ltstr>::iterator upper_bound=lower_bound;
if(lower_bound!=sum.begin())
upper_bound--;
if(lower_bound==sum.end())
lower_bound--;
int cur_min=min(abs((*lower_bound).first-to_search),abs((*upper_bound).first-to_search));
if(cur_min<closest)
{
closest=cur_min;
startId=iter-my_vec.begin();
endId=abs((*lower_bound).first-to_search)<abs((*upper_bound).first-to_search)?(*lower_bound).second-1:(*upper_bound).second-1;
}
}
}
#include<set>
#include<vector>
#include<algorithm>
#include<iostream>
#include<iterator>
using namespace std;
struct ltstr
{
bool operator()(pair<int,int> p1, pair<int,int> p2) const
{
return p1.first<p2.first;
}
};
void FindRange(vector<int> X,int val,int& startId, int& endId)
{
int size=X.size();
//preprocessing sum
set<pair<int,int>,ltstr> sum;
vector<pair<int,int>> my_vec;
int cur_sum=0;
for(int i=0;i<=size;i++)
{
sum.insert(pair<int,int>::pair(cur_sum,i));
my_vec.push_back(pair<int,int>::pair(cur_sum,i));
if(i<size)cur_sum+=X[i];
}
int closest=INT_MAX;
for(vector<pair<int,int>>::iterator iter=my_vec.begin();iter!=(my_vec.end()-1);iter++)
{
//remove already searched range so the output range is valid
pair<int,int> to_erase=*iter;
sum.erase(*iter);
int to_search=(*iter).first+val;
//search for closest value with lower bound and upper bound
set<pair<int,int>,ltstr>::iterator lower_bound=sum.lower_bound(pair<int,int>::pair(to_search,0));
set<pair<int,int>,ltstr>::iterator upper_bound=lower_bound;
if(lower_bound!=sum.begin())
upper_bound--;
if(lower_bound==sum.end())
lower_bound--;
int cur_min=min(abs((*lower_bound).first-to_search),abs((*upper_bound).first-to_search));
if(cur_min<closest)
{
closest=cur_min;
startId=iter-my_vec.begin();
endId=abs((*lower_bound).first-to_search)<abs((*upper_bound).first-to_search)?(*lower_bound).second-1:(*upper_bound).second-1;
}
}
}
Friday, February 22, 2013
longest increasing subsequence
#include<iostream>
#include<vector>
#include<set>
using namespace std;
void LongestSubSequence(vector<int> X)
{
int n=X.size();
vector<int> M(n+1);
int L=0;
for(int i=0;i<n;i++)
{
int j;
if(L==0)j=0;
else
{
for(j=1;j<=L;j++)
{
if(X[M[j]]>X[i])
break;
}
j--;
}
if(j==L || X[i]<X[M[j+1]])
{
M[j+1]=i;
L=max(L,j+1);
}
}
cout<<L<<endl;
}
linked list revisited
#include<list>
#include<iterator>
#include<iostream>
using namespace std;
void TestList()
{
list<int> L;
L.push_back(0);
L.push_front(1);
L.insert(++L.begin(),2);
copy(L.begin(),L.end(),ostream_iterator<int>(cout," "));
}
knapsack problem revisited
#include<iostream>
#include<vector>
using namespace std;
void Knapsack(vector<int> v,vector<int> w,int W)
{
//unbounded
vector<int> m(W);
m[0]=0;
for(int i=1;i<=W;i++)
{
int maximum=0;
for(int j=0;j<w.size();j++)
{
if(i>=w[j])
maximum=max(maximum,v[j]+m[i-w[j]]);
}
m[i]=maximum;
}
//bounded
vector<vector<int>> m2;
m2.resize(v.size());
for(int i=0;i<v.size();i++)
{
m2[i].resize(W);
fill(m2[i].begin(),m2[i].end(),0);
}
for(int i=1;i<v.size();i++)
{
for(int j=0;j<W;j++)
{
m2[i][j]=m2[i-1][j];
if(j>w[i])
m2[i][j]=max(m2[i][j],m2[i-1][j-w[i]]+v[i]);
}
}
}
matrix multiplication chain can also be solved by dp
set operation
void ThreeCoke()
{
int a[4]={1,2,3,4},b[4]={4,5,6,7};
set<int> A(a,a+4),B(b,b+4);
cout<<"set A: ";
copy(A.begin(),A.end(),ostream_iterator<int>(cout," "));
cout<<endl;
cout<<"set B: ";
copy(B.begin(),B.end(),ostream_iterator<int>(cout," "));
cout<<endl;
set<int> C;
cout<<"Union:";
set_union(A.begin(),A.end(),B.begin(),B.end(),ostream_iterator<int>(cout," "));
cout<<endl;
cout<<"Intersection:";
set_intersection(A.begin(),A.end(),B.begin(),B.end(),inserter(C,C.begin()));
cout<<endl;
copy(C.begin(),C.end(),ostream_iterator<int>(cout," "));
}
check sum
find two numbers that sum up to a certain number
1. if it is a sort array.
2. if it is a tree (bst)
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
struct Node
{
Node* L;
Node* R;
int val;
};
void FindTwo(Node* root,int val)
{
stack<Node*> stack1,stack2;
Node* cur_node=root;
while(cur_node)
{
stack1.push(cur_node);
cur_node=cur_node->L;
}
cur_node=root;
while(cur_node)
{
stack2.push(cur_node);
cur_node=cur_node->R;
}
while(true)
{
Node *node1=stack1.top(),*node2=stack2.top();
if(!node1 || !node2)
break;
int val1=node1->val,val2=node2->val;
if(val1+val2==val)
{
cout<<val1<<" "<<val2<<endl;
break;
}
else if(val1+val2<val)
{
stack1.pop();
Node* cur_node=node1->R;
while(cur_node)
{
stack1.push(cur_node);
cur_node=cur_node->L;
}
}
else if(val1+val2>=val)
{
stack2.pop();
Node* cur_node=node2->L;
while(cur_node)
{
stack2.push(cur_node);
cur_node=cur_node->R;
}
}
}
}
1. if it is a sort array.
if(A[1st_index] + A[2nd_index] < x)
2nd_index--;
else if (A[1st_index] + A[2nd_index] > x)
1st_index++;
else
print 1st_index,2nd_index;
do this until 2nd_index > 1st_index
2. if it is a tree (bst)
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
struct Node
{
Node* L;
Node* R;
int val;
};
void FindTwo(Node* root,int val)
{
stack<Node*> stack1,stack2;
Node* cur_node=root;
while(cur_node)
{
stack1.push(cur_node);
cur_node=cur_node->L;
}
cur_node=root;
while(cur_node)
{
stack2.push(cur_node);
cur_node=cur_node->R;
}
while(true)
{
Node *node1=stack1.top(),*node2=stack2.top();
if(!node1 || !node2)
break;
int val1=node1->val,val2=node2->val;
if(val1+val2==val)
{
cout<<val1<<" "<<val2<<endl;
break;
}
else if(val1+val2<val)
{
stack1.pop();
Node* cur_node=node1->R;
while(cur_node)
{
stack1.push(cur_node);
cur_node=cur_node->L;
}
}
else if(val1+val2>=val)
{
stack2.pop();
Node* cur_node=node2->L;
while(cur_node)
{
stack2.push(cur_node);
cur_node=cur_node->R;
}
}
}
}
Thursday, February 21, 2013
some small typos of program writings
1.
char a[10][256]={
"..",
"..",
...
".."
}; //dont miss the semicolon
2.
Node* node1,node2; //wrong!!
Node *node1,*node2;
3.
int a[5]={1,2,3,4,5};
vector<int> b(a,a+5); NOT b(a,a+4)
4.
pay attention to return type
and if it returns int, dont write return; write return -1 instead.
5.
if
else if //not elseif
char a[10][256]={
"..",
"..",
...
".."
}; //dont miss the semicolon
2.
Node* node1,node2; //wrong!!
Node *node1,*node2;
3.
int a[5]={1,2,3,4,5};
vector<int> b(a,a+5); NOT b(a,a+4)
4.
pay attention to return type
and if it returns int, dont write return; write return -1 instead.
5.
if
else if //not elseif
map english words to byte
char map_english_words(string word)
{
char xorsum=0;
for(int i=0;i<word.length();i++)
{
xorsum^=word[i];
}
return xorsum;
}
char map=map_english_words("k");
char buffer[256];
itoa((int)map,buffer,2);
cout<<buffer<<endl;
system("pause");
(bitwise output)
____________________________________
huffman coding
dynamic programming
the max coin problem
#include<iostream>
#include<vector>
using namespace std;
int max_coin(vector<int> pots)
{
vector<vector<int>> dp_table;
int pot_num=pots.size();
dp_table.resize(pot_num);
for(int i=0;i<pot_num;i++)
{
dp_table[i].resize(pot_num);
for(int j=0;j<i;j++)
dp_table[i][j]=0;
}
for(int k=0;k<pot_num;k++)
{
for(int i=0;i<pot_num;i++)
{
int j=i+k;
if(j>=pot_num)
continue;
double pots1,pots2;
if(i+2<pots.size() && j-1>=0)
pots1=pots[i]+min(dp_table[i+2][j],dp_table[i+1][j-1]);
else
pots1=pots[i];
if(i+1<pots.size() && j-2>=0)
pots2=pots[j]+min(dp_table[i+1][j-1],dp_table[i][j-2]);
else
pots2=pots[j];
dp_table[i][j]=max(pots1,pots2);
}
}
return dp_table[0][pot_num-1];
}
design a web browser like Chrome
Chrome stores everything in separate process, which implies that the parent process would keep a hashmap of all the processes. The key would be the index and the value would be the process. The process would provide the details with regard to tab-content. Movement of tabs is just swapping of hash-keys.
Each tab is a process and have URL-handler. The handler would call a factory of protocol, such as httpFactory, ftpFactory etc. Each protocol handler has a retrieving-engine and rendering-engine. The browser would retrieve and render using factory.
I cant state definitively how Chrome handles the rendering threads - but I would assume that each tab has its own rendering thread. I wouldnt see the point of going through all the effort of process isolating the tabs, only to tie them all together on a common rendering thread. They would all have the opportunity to interfere with each other.
Don't confuse threads and processes. Each process will have it's own ui thread, but likely also it's own message pump.
Each tab is a process and have URL-handler. The handler would call a factory of protocol, such as httpFactory, ftpFactory etc. Each protocol handler has a retrieving-engine and rendering-engine. The browser would retrieve and render using factory.
I cant state definitively how Chrome handles the rendering threads - but I would assume that each tab has its own rendering thread. I wouldnt see the point of going through all the effort of process isolating the tabs, only to tie them all together on a common rendering thread. They would all have the opportunity to interfere with each other.
Don't confuse threads and processes. Each process will have it's own ui thread, but likely also it's own message pump.
Interestingly, using multiple processes means Google Chrome can have its own Task Manager (shown below), which you can get to by right clicking on the browser's title bar. This Task Manager lets you track resource usage for each web app and plug-in, rather than for the entire browser. It also lets you kill any web apps or plug-ins that have stopped responding, without having to restart the entire browser.
Wednesday, February 20, 2013
some old, but useful tree algorithms
1. in-order traversal to test if a binary search tree
#include<iostream>
#include<stack>
using namespace std;
struct TreeNode
{
int value;
TreeNode* left;
TreeNode* right;
};
bool IsBST(TreeNode* root)
{
stack<TreeNode*> my_stack;
TreeNode* prev=nullptr;
TreeNode* cur_node=root;
while(cur_node || !my_stack.empty())
{
if(cur_node)
{
my_stack.push(cur_node);
cur_node=cur_node->left;
}
else
{
TreeNode* top_node=my_stack.top();
if(prev && top_node->value<=prev->value)
return false;
prev=top_node;
cur_node=prev->right;
my_stack.pop();
}
}
return true;
}
2. a recursive algorithm to test if a binary search tree
#include<iostream>
#include<stack>
using namespace std;
struct TreeNode
{
int value;
TreeNode* left;
TreeNode* right;
};
bool IsBST(TreeNode* root)
{
stack<TreeNode*> my_stack;
TreeNode* prev=nullptr;
TreeNode* cur_node=root;
while(cur_node || !my_stack.empty())
{
if(cur_node)
{
my_stack.push(cur_node);
cur_node=cur_node->left;
}
else
{
TreeNode* top_node=my_stack.top();
if(prev && top_node->value<=prev->value)
return false;
prev=top_node;
cur_node=prev->right;
my_stack.pop();
}
}
return true;
}
2. a recursive algorithm to test if a binary search tree
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct
node
{
int
data;
struct
node* left;
struct
node* right;
};
int
isBSTUtil(
struct
node* node,
int
min,
int
max);
/* Returns true if the given tree is a binary search tree
(efficient version). */
int
isBST(
struct
node* node)
{
return
(isBSTUtil(node, INT_MIN, INT_MAX));
}
/* Returns true if the given tree is a BST and its
values are >= min and <= max. */
int
isBSTUtil(
struct
node* node,
int
min,
int
max)
{
/* an empty tree is BST */
if
(node==NULL)
return
1;
/* false if this node violates the min/max constraint */
if
(node->data < min || node->data > max)
return
0;
/* otherwise check the subtrees recursively,
tightening the min or max constraint */
return
isBSTUtil(node->left, min, node->data-1) &&
// Allow only distinct values
isBSTUtil(node->right, node->data+1, max);
// Allow only distinct values
}
bool IsBST(Node* root,int& mymin,int& mymax)
{
if(!root)
{
mymin=INT_MAX;
mymax=INT_MIN;
return true;
}
int min1,max1,min2,max2;
bool l=IsBST(root->L,min1,max1);
bool r=IsBST(root->R,min2,max2);
mymin=min(min1,min2);
mymin=min(mymin,root->val);
mymax=max(max1,max2);
mymax=max(mymax,root->val);
return l && r && max1<root->val && min2>root->val;
}
check if a tree is balanced
#include<iostream>
struct node
{
int data;
struct node* left;
struct node* right;
};
bool IsBalanced(struct node* root,int& height)
{
if(root==NULL)
{
height=0;
return true;
}
int lh,rh;
bool l,r;
l=IsBalanced(root->left,lh);
r=IsBalanced(root->right,rh);
height=(lh>rh?lh:rh)+1;
if(abs(lh-rh)>=2)
return false;
else return l&&r;
}
Subscribe to:
Posts (Atom)