Вы находитесь на странице: 1из 6

We can conclude a recursive function :

For left child range will be , [ roots Min range , root value -1 ]
For right child range will be , [ roots value + 1, to roots Max ]

APPROACH 1 :
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isValidBST(TreeNode* root) {
if(!root) return true;
return isValid(root, INT_MIN, INT_MAX);
}
bool isValid(TreeNode* root, int min, int max) {
if(root==NULL)return true;
// We will consider that root is valid and now we will check the validity of its left and right child
bool left=1,right=1;
// Check the validity of left child
if(root->left) {
if(root->val > root->left->val && (root->left->val >=min ) && (root->left->val <= max ) ){
left=isValid(root->left, min, root->val -1 );
}
else left=0;
}
// Check the validity of right child
if(root->right) {
if(root->right->val > root->val && (root->right->val >=min ) && (root->right->val <= max ) )
right=isValid(root->right , root->val +1 , max );
else right=0;
}
// If both left & right child is valid then the node is vlaid.
return (left & right);
}
};

https://leetcode.com/problems/word-ladder-ii/
In this problem you need to change your idea.
It is a BFS + Path Finding problem.
Here you need to keep track of each and every path. But, when you are deleting some words from the
dictionary, it is not helping you. That is why it is missing some paths.
So, if we keep track of minimum cost of making a string it will help us in finding the shortest path. We do
not need to delete any string from the dict.

class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
unordered_map<string, unordered_set<string>> prevMap;
vector<vector<string>> solutions;
deque<string> q[2];
bool done=false;
int current=0;
int next=1;
unordered_map<string,int>cost;
int INF=10000000;
for( auto e : dict){
cost[e]=INF;
}
cost[start]=0;
cost[end]=INF;
q[current].push_back(start);
while(!q[current].empty()){
string c=q[current].front();
q[current].pop_front();
string prev=c;
for(int i=0;i<c.size();i++)
for(int k='a';k<='z';k++){
if(c[i]!=k){
char beforeChange=c[i];
c[i]=k;
if(c==end && cost[c]>=cost[prev]+1) {
cost[c]=cost[prev]+1;
prevMap[end].insert(prev); // in case end can be not in dict
//q[next].push_back()
done=true;
} else if(dict.find(c)!=dict.end() && cost[c]>=cost[prev]+1 ){
//if(prevMap.find(c)==prevMap.end() )

if(cost[c]==INF)
{
q[next].push_back(c);
}
cost[c]=cost[prev]+1;
prevMap[c].insert(prev);
}
c[i]=beforeChange;
}
}
// we must not delete anything from the dict.
// for(auto s: q[next]){
// dict.erase(s);
// }
if(q[current].empty()) {
if(done) break;
current=next;
next=!current;
}
}
if(done){
deque<string> res;
res.push_back(end);
printPrevRec(res, start, prevMap, solutions);
}
return solutions;
}
void printPrevRec(deque<string>& res, string& start, unordered_map<string,
unordered_set<string>>& pmap, vector<vector<string>>& solutions){
for(auto e: pmap[res.back()]){
res.push_back(e);
if(e==start){
vector<string> res1;
for(auto it=res.rbegin(); it!=res.rend(); it++) {
res1.push_back(*it);
}
solutions.push_back(res1);
} else {
printPrevRec(res, start, pmap, solutions);
}
res.pop_back();
}
}
};

//https://leetcode.com/problems/scramble-string/
You just think like this.
a =great , string length is 5
b=rgate
so, we can say that we need to know is ( 0, 4 ) of a is scamble word of ( 0,4 ) of b.
so, we can say that , need to know is ( left,right ) of a is scamble word of ( x , y ) of b.
So, in each step we have as follows.
We must divide them into two part (as it is binary tree and not leaf)
Here we have two option,
1) just divide them two parts F(left, right , x , y) = F( 0,4,0,4 )

great
rgate
01234
Here we divide them into two parts F(0,1,0,1) & F(2,4,2,4)

Or, we can reverse them.


For example,

great
ategr
01234
Here we divide them into two partsF (0,1 , 3,4 ) & F(2,4,0,2 )
We can say (left, right, x,y) can be achievable if any of the two parts is true.
That is , We can say F(0,4,0,4) be achievable if F(0,1,0,1) &F (2,4,2,4) OR (F(0,1 , 3,4 ) &F (2,4,0,2 ) ) is
true.

I did it with this idea recursively.

class Solution {
public:
#define Mx 30
int dp[Mx][Mx][Mx][Mx];
int N;
string a,b;
bool solve(int l , int r , int x, int y ){
if(l==r ){
return (a[l]==b[x]);
}
int &ret=dp[l][r][x][y];
if(ret!=-1)return ret;
ret=0;
int i,j;
for(int i = l , j=x ; i< r ;i++ , j++ ){
ret|=( solve(l,i,x,j ) & solve(i+1,r,j+1,y ) );
ret|=( solve(l,i,y-(i-l) , y ) & solve(i+1,r , x, y-(i-l)-1 ) );
}
return ret;
}
bool isScramble( string s1, string s2 ) {
if(s1.length()!=s2.length())return false;
if(s1==s2)return true;
memset(dp,-1,sizeof dp);
a=s1,b=s2;
N=s1.length();
if(s1==s2)return true;
return solve(0,N-1,0,N-1);
}
};

Вам также может понравиться