Recursion Master Notes Hinglish LeetCode
Recursion Master Notes Hinglish LeetCode
Sir Tip
Recursion likhne se pehle ye sentence bolo: solve(i, ...) ka matlab kya hai? Agar function ka meaning clear nahi hai, code jungle ban jayega.
return answer;
}
Mathematical form: F(n) = combine(current work, F(n-1)) with F(0) known. For branching: F(i) = F(choice1) + F(choice2) + ...
Approach Hinglish
Print before recursive call. Pehle current number ka kaam, fir smaller problem n-1.
Equation / Recurrence
print(n) = output n then print(n-1); base: n == 0
void printNto1(int n) {
if (n == 0) return;
cout << n << " ";
Complexity + Tips
Time O(n), stack O(n).
Work before call means output going down.
3.2 Print 1 to N
Question samjho
Input n diya hai. 5 ke liye 1 2 3 4 5 print karna hai.
Approach Hinglish
Pehle smaller numbers print karao, fir current n print karo.
Equation / Recurrence
print(n) = print(n-1) then output n; base: n == 0
void print1toN(int n) {
if (n == 0) return;
print1toN(n - 1);
cout << n << " ";
}
Complexity + Tips
Time O(n), stack O(n).
Work after call means output returning time pe.
Approach Hinglish
sum(n) ka meaning: first n numbers ka sum. Current n + remaining n-1 ka sum.
Equation / Recurrence
S(n) = n + S(n-1), S(0)=0
int sumN(int n) {
if (n == 0) return 0;
return n + sumN(n - 1);
}
Complexity + Tips
Time O(n), stack O(n).
Formula direct n*(n+1)/2 bhi hai, but recursion concept ke liye relation important hai.
3.4 Factorial
Question samjho
n! n se 1 tak multiplication hai. Example 5! = 120.
Approach Hinglish
fact(n) ka meaning: n factorial. Current n multiply with factorial of n-1.
Equation / Recurrence
F(n) = n * F(n-1), F(0)=1
3.5 Fibonacci
Question samjho
Nth Fibonacci nikalna hai jahan 0,1,1,2,3,5... sequence hoti hai.
Approach Hinglish
fib(n) depends on previous two terms. Ye branching recursion ka first example hai.
Equation / Recurrence
F(n)=F(n-1)+F(n-2), F(0)=0, F(1)=1
int fib(int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
Complexity + Tips
Time O(2^n), stack O(n).
Repeated calls hoti hain. Later DP/memoization lagti hai.
Equation cheat
Linear recursion: T(n)=T(n-1)+O(1) -> O(n). Tree binary recursion: T(n)=2T(n-1)+O(1) approx O(2^n). Divide recursion: T(n)=T(n/2)+O(1) -> O(log n), and
T(n)=2T(n/2)+O(n) -> O(n log n).
Approach Hinglish
x^n = x * x^(n-1).
Equation / Recurrence
P(x,n)=x*P(x,n-1), P(x,0)=1
Complexity + Tips
Time O(n), stack O(n).
Equation / Recurrence
P(n)=P(n/2)^2 if even; x*P(n/2)^2 if odd; base n=0
Complexity + Tips
Time O(log n), stack O(log n).
LeetCode Pow(x,n) me negative n and INT_MIN handle karna hota hai.
Approach Hinglish
n ko long long me lo kyunki INT_MIN ka abs overflow kar sakta hai. Agar n negative hai to answer = 1 / pow(x, -n).
Equation / Recurrence
pow(x,n): n<0 -> 1/pow(x,-n)
Complexity + Tips
Time O(log n), stack O(log n).
Most common bug: n = -2147483648.
Approach Hinglish
Every call n/10 karte jao. Har removed digit ke liye +1.
Equation / Recurrence
C(n)=1+C(n/10), base n<10 -> 1
int countDigits(int n) {
if (n < 10) return 1;
return 1 + countDigits(n / 10);
}
Complexity + Tips
Time O(log10 n), stack O(log10 n).
Approach Hinglish
Last digit n%10 add karo, remaining n/10 pe recursion.
Equation / Recurrence
S(n)=n%10 + S(n/10), S(0)=0
int sumDigits(int n) {
if (n == 0) return 0;
return n % 10 + sumDigits(n / 10);
}
Complexity + Tips
Time O(digits), stack O(digits).
Approach Hinglish
Recursive version: sumDigits(n), if <10 return, else repeat. Math version faster hai.
Equation / Recurrence
DR(n)=DR(sumDigits(n)); base n<10
int addDigitsRec(int n) {
if (n < 10) return n;
int s = 0, x = n;
while (x) { s += x % 10; x /= 10; }
return addDigitsRec(s);
}
Complexity + Tips
Time O(log n repeated), stack small.
Math: n==0 ? 0 : 1 + (n-1)%9.
Approach Hinglish
At index i, bas arr[i] <= arr[i+1] check karo and rest array sorted hai ya nahi.
Equation / Recurrence
sorted(i)=arr[i]<=arr[i+1] AND sorted(i+1)
Complexity + Tips
Time O(n), stack O(n).
Approach Hinglish
Current index check karo. Nahi mila to i+1 se search.
Equation / Recurrence
search(i)=i if a[i]==target else search(i+1)
Complexity + Tips
Time O(n), stack O(n).
Approach Hinglish
Middle compare karo. Target chhota hai to left half, bada hai to right half.
Equation / Recurrence
T(n)=T(n/2)+O(1)
Complexity + Tips
Time O(log n), stack O(log n).
Overflow-safe mid use karo.
Approach Hinglish
Two pointers l and r. Swap, then inner part reverse.
Equation / Recurrence
rev(l,r): swap a[l],a[r] + rev(l+1,r-1)
Complexity + Tips
Time O(n), stack O(n).
Approach Hinglish
Index i se end tak ka sum = a[i] + sum(i+1).
Equation / Recurrence
S(i)=a[i]+S(i+1), S(n)=0
Complexity + Tips
Time O(n), stack O(n).
Approach Hinglish
Left and right characters compare karo. Agar equal hain to inner substring check karo.
Equation / Recurrence
pal(l,r)=s[l]==s[r] AND pal(l+1,r-1)
Complexity + Tips
Time O(n), stack O(n).
Approach Hinglish
Two pointers swap, then move inward.
Equation / Recurrence
rev(l,r): swap + rev(l+1,r-1)
Complexity + Tips
Time O(n), stack O(n).
Approach Hinglish
Index wise build karo. Agar current char unwanted hai to skip, else add.
Equation / Recurrence
ans(i)=skip/take current + ans(i+1)
Complexity + Tips
Time O(n^2) due to string copy, stack O(n).
Better use reference output string for O(n).
Approach Hinglish
Har character ke liye 2 choices: include or exclude.
Equation / Recurrence
F(i)=F(i+1 without s[i]) + F(i+1 with s[i])
Complexity + Tips
Time O(2^n * n), stack O(n).
Subsequence problems = include/exclude bell bajao.
// include
curr.push_back(nums[i]);
solve(i + 1, nums, curr);
Approach Hinglish
Har element ke liye exclude/include. Base pe current subset answer me push.
Equation / Recurrence
Total subsets = 2^n
class Solution {
public:
vector<vector<int>> ans;
void solve(int i, vector<int>& nums, vector<int>& cur) {
if (i == [Link]()) {
ans.push_back(cur);
return;
}
solve(i + 1, nums, cur); // not take
cur.push_back(nums[i]); // take
solve(i + 1, nums, cur);
cur.pop_back(); // backtrack
}
vector<vector<int>> subsets(vector<int>& nums) {
vector<int> cur;
solve(0, nums, cur);
return ans;
}
};
Complexity + Tips
Time O(n*2^n), stack O(n), answer space O(n*2^n).
Question samjho: subset me order same nahi, bas collection chahiye.
Approach Hinglish
Sort karo. At each recursion level same value repeat choose mat karo.
Equation / Recurrence
Skip duplicates when i > start and nums[i]==nums[i-1]
class Solution {
public:
vector<vector<int>> ans;
void dfs(int start, vector<int>& nums, vector<int>& cur) {
ans.push_back(cur);
for (int i = start; i < [Link](); i++) {
if (i > start && nums[i] == nums[i - 1]) continue;
cur.push_back(nums[i]);
dfs(i + 1, nums, cur);
cur.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort([Link](), [Link]());
vector<int> cur;
dfs(0, nums, cur);
Complexity + Tips
Time O(n*2^n), stack O(n).
Duplicate handling ka mantra: sort + same level duplicate skip.
Approach Hinglish
Current element ko lo ya mat lo. Sum reduce karte jao.
Equation / Recurrence
count(i,sum)=count(i+1,sum)+count(i+1,sum-a[i])
Complexity + Tips
Time O(2^n), stack O(n).
DP me same state (i,sum) memoize hoga.
Approach Hinglish
Each number ke liye two choices: plus or minus.
Equation / Recurrence
ways(i,sum)=ways(i+1,sum+a[i])+ways(i+1,sum-a[i])
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
unordered_map<string,int> memo;
function<int(int,int)> dfs = [&](int i, int sum) -> int {
if (i == [Link]()) return sum == target;
string key = to_string(i) + "," + to_string(sum);
if ([Link](key)) return memo[key];
return memo[key] = dfs(i + 1, sum + nums[i]) + dfs(i + 1, sum - nums[i]);
};
return dfs(0, 0);
}
};
Complexity + Tips
Without memo O(2^n), with memo O(n*range).
Pure recursion se TLE aa sakta hai, but recursion thinking yahi hai.
9. Combination Pattern
Question feel
Combination me usually elements ka order output me matter nahi karta. [2,3] and [3,2] same combination hote hain. Isliye recursion me start index maintain
karte hain, taaki peeche na jao.
Approach Hinglish
At index i, ya current number repeatedly lo, ya next index pe jao. Reuse allowed, so take ke baad i same rahega.
Equation / Recurrence
take: solve(i,target-a[i]); skip: solve(i+1,target)
class Solution {
public:
vector<vector<int>> ans;
void dfs(int i, vector<int>& cand, int target, vector<int>& cur) {
if (target == 0) { ans.push_back(cur); return; }
if (i == [Link]() || target < 0) return;
cur.push_back(cand[i]);
dfs(i, cand, target - cand[i], cur); // reuse same
cur.pop_back();
Complexity + Tips
Exponential, stack O(target/min).
Reuse allowed means index same after take.
Approach Hinglish
Sort karo. For-loop recursion use karo. Same level duplicate skip. Next call i+1 because each element once.
Equation / Recurrence
dfs(start,target), choose i from start..n-1
class Solution {
public:
vector<vector<int>> ans;
void dfs(int start, vector<int>& a, int target, vector<int>& cur) {
if (target == 0) { ans.push_back(cur); return; }
for (int i = start; i < [Link](); i++) {
if (i > start && a[i] == a[i - 1]) continue;
if (a[i] > target) break;
cur.push_back(a[i]);
dfs(i + 1, a, target - a[i], cur);
cur.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort([Link](), [Link]());
vector<int> cur;
dfs(0, candidates, target, cur);
Complexity + Tips
Exponential, stack O(n).
Same level duplicate skip is the crown jewel here.
Approach Hinglish
Start index, remaining k, remaining sum. Choose next increasing number.
Equation / Recurrence
dfs(start,kLeft,sumLeft)
class Solution {
public:
vector<vector<int>> ans;
void dfs(int start, int k, int target, vector<int>& cur) {
if (k == 0 && target == 0) { ans.push_back(cur); return; }
if (k == 0 || target < 0) return;
for (int x = start; x <= 9; x++) {
cur.push_back(x);
dfs(x + 1, k - 1, target - x, cur);
cur.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
vector<int> cur;
dfs(1, k, n, cur);
return ans;
}
};
Complexity + Tips
Small bounded search.
Question me exactly k numbers word important hai.
Approach Hinglish
For-loop with start. Choose number, then move to next.
Equation / Recurrence
dfs(start), stop when [Link]()==k
class Solution {
public:
vector<vector<int>> ans;
void dfs(int start, int n, int k, vector<int>& cur) {
if ([Link]() == k) { ans.push_back(cur); return; }
for (int x = start; x <= n; x++) {
cur.push_back(x);
dfs(x + 1, n, k, cur);
cur.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
Complexity + Tips
O(k*C(n,k)), stack O(k).
Pruning: remaining numbers insufficient ho to loop early stop.
Approach Hinglish
At every position, any unused number choose karo.
Equation / Recurrence
n choices then n-1 then ... = n!
class Solution {
public:
vector<vector<int>> ans;
void dfs(vector<int>& nums, vector<int>& cur, vector<int>& used) {
if ([Link]() == [Link]()) { ans.push_back(cur); return; }
for (int i = 0; i < [Link](); i++) {
if (used[i]) continue;
used[i] = 1;
cur.push_back(nums[i]);
dfs(nums, cur, used);
cur.pop_back();
used[i] = 0;
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<int> cur, used([Link](), 0);
dfs(nums, cur, used);
return ans;
}
};
Complexity + Tips
Time O(n*n!), stack O(n).
Use visited when input array should stay unchanged.
Approach Hinglish
Index pos decide karta hai kis place pe kaunsa number fix hoga. Swap each candidate into pos.
Equation / Recurrence
perm(pos): swap pos with i, perm(pos+1), undo
Complexity + Tips
Time O(n*n!), stack O(n).
Second swap compulsory. Warna array polluted ho jayega.
Approach Hinglish
Sort + used array. Same value duplicate tab skip karo jab previous same unused ho.
Equation / Recurrence
if i>0 && nums[i]==nums[i-1] && !used[i-1] skip
class Solution {
public:
vector<vector<int>> ans;
void dfs(vector<int>& nums, vector<int>& cur, vector<int>& used) {
if ([Link]() == [Link]()) { ans.push_back(cur); return; }
for (int i = 0; i < [Link](); i++) {
if (used[i]) continue;
if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue;
used[i] = 1;
cur.push_back(nums[i]);
dfs(nums, cur, used);
cur.pop_back();
used[i] = 0;
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort([Link](), [Link]());
vector<int> cur, used([Link](), 0);
dfs(nums, cur, used);
return ans;
}
};
Complexity + Tips
Time O(n*n!), stack O(n).
Duplicate permutations me ye condition gold hai.
Approach Hinglish
Character letter hai to lower/upper two choices. Digit hai to one choice.
Equation / Recurrence
F(i)=two calls for alphabet, one call for digit
class Solution {
public:
vector<string> ans;
void dfs(string& s, int i) {
if (i == [Link]()) { ans.push_back(s); return; }
Complexity + Tips
Time O(2^letters * n), stack O(n).
Approach Hinglish
Har digit ke possible letters pe loop. One letter choose, next digit solve.
Equation / Recurrence
branching product of letters per digit
class Solution {
public:
vector<string> ans;
vector<string> mp = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
void dfs(string& digits, int i, string& cur) {
if (i == [Link]()) { ans.push_back(cur); return; }
for (char ch : mp[digits[i] - '0']) {
cur.push_back(ch);
dfs(digits, i + 1, cur);
cur.pop_back();
}
}
vector<string> letterCombinations(string digits) {
if ([Link]()) return {};
string cur;
dfs(digits, 0, cur);
return ans;
}
};
Complexity + Tips
Time O(4^n*n), stack O(n).
Question keypad hai, so mapping first write karo.
Approach Hinglish
Open bracket tab tak laga sakte ho jab open < n. Close tab laga sakte ho jab close < open.
Equation / Recurrence
valid condition: close <= open <= n
Complexity + Tips
Catalan count, stack O(n).
Close bracket kabhi open se zyada nahi hone dena.
Approach Hinglish
Start index se end tak substring choose karo. Agar palindrome hai to choose and solve remaining.
Equation / Recurrence
dfs(start), choose s[start..end] if palindrome
class Solution {
public:
vector<vector<string>> ans;
bool pal(string& s, int l, int r) {
while (l < r) if (s[l++] != s[r--]) return false;
return true;
}
void dfs(int start, string& s, vector<string>& cur) {
if (start == [Link]()) { ans.push_back(cur); return; }
for (int end = start; end < [Link](); end++) {
if (pal(s, start, end)) {
cur.push_back([Link](start, end - start + 1));
dfs(end + 1, s, cur);
cur.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
vector<string> cur;
dfs(0, s, cur);
return ans;
}
};
Complexity + Tips
Time approx O(n*2^n), stack O(n).
Approach Hinglish
At each part choose length 1,2,3. Validate part.
Equation / Recurrence
dfs(index, partsUsed)
class Solution {
public:
vector<string> ans;
bool valid(string part) {
if ([Link]() > 1 && part[0] == '0') return false;
int val = stoi(part);
return val <= 255;
}
void dfs(string& s, int idx, vector<string>& parts) {
if ([Link]() == 4) {
if (idx == [Link]()) ans.push_back(parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3]);
return;
}
for (int len = 1; len <= 3 && idx + len <= [Link](); len++) {
string part = [Link](idx, len);
if (!valid(part)) continue;
parts.push_back(part);
dfs(s, idx + len, parts);
parts.pop_back();
}
}
vector<string> restoreIpAddresses(string s) {
vector<string> parts;
dfs(s, 0, parts);
return ans;
}
};
Complexity + Tips
Constant-ish bounded search.
Question samjho: IP exactly 4 blocks. Extra/missing digits invalid.
Approach Hinglish
Move allowed directions me jao. Visited mark karo, recursive call, then unmark.
Equation / Recurrence
dfs(r,c), stop at destination
void dfs(int r, int c, vector<vector<int>>& maze, vector<vector<int>>& vis, string& path, vector<string>& ans) {
int n = [Link]();
if (r == n - 1 && c == n - 1) { ans.push_back(path); return; }
string dir = "DLRU";
int dr[4] = {1,0,0,-1};
int dc[4] = {0,-1,1,0};
Complexity + Tips
Worst exponential.
Visited zaroori, warna loop me phas sakte ho.
Approach Hinglish
Har cell se DFS start karo. Current char match hona chahiye. Temporarily visited mark karo.
Equation / Recurrence
dfs(r,c,idx), idx==[Link] true
class Solution {
public:
bool dfs(vector<vector<char>>& b, string& w, int r, int c, int idx) {
if (idx == [Link]()) return true;
int m = [Link](), n = b[0].size();
if (r<0 || c<0 || r>=m || c>=n || b[r][c] != w[idx]) return false;
char old = b[r][c];
b[r][c] = '#';
bool ok = dfs(b,w,r+1,c,idx+1) || dfs(b,w,r-1,c,idx+1) || dfs(b,w,r,c+1,idx+1) || dfs(b,w,r,c-1,idx+1);
b[r][c] = old;
return ok;
}
bool exist(vector<vector<char>>& board, string word) {
for (int r=0;r<[Link]();r++)
for (int c=0;c<board[0].size();c++)
if (dfs(board, word, r, c, 0)) return true;
return false;
}
};
Complexity + Tips
Time O(m*n*4^L), stack O(L).
Use board cell as visited marker to save space.
Approach Hinglish
Jab unvisited land mile, count++ and DFS se pura island sink/visit kar do.
Equation / Recurrence
DFS visits each cell once
class Solution {
public:
void dfs(vector<vector<char>>& g, int r, int c) {
Complexity + Tips
Time O(m*n), stack O(m*n) worst.
This is DFS recursion, not choice recursion.
Approach Hinglish
Each DFS returns area of current island. Mark visited by setting 0.
Equation / Recurrence
area(r,c)=1+areas(neighbors)
class Solution {
public:
int dfs(vector<vector<int>>& g, int r, int c) {
int m=[Link](), n=g[0].size();
if(r<0||c<0||r>=m||c>=n||g[r][c]==0) return 0;
g[r][c]=0;
return 1 + dfs(g,r+1,c) + dfs(g,r-1,c) + dfs(g,r,c+1) + dfs(g,r,c-1);
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int best=0;
for(int r=0;r<[Link]();r++) for(int c=0;c<grid[0].size();c++)
best=max(best, dfs(grid,r,c));
return best;
}
};
Complexity + Tips
Time O(m*n), stack O(m*n).
Approach Hinglish
Row by row queen place karo. Column and diagonals track karo.
Equation / Recurrence
col[c], diag1[r-c+n-1], diag2[r+c]
class Solution {
public:
vector<vector<string>> ans;
void dfs(int r, int n, vector<string>& board, vector<int>& col, vector<int>& d1, vector<int>& d2) {
Complexity + Tips
Rough O(n!), stack O(n).
Diagonal equations yad rakho: r-c constant, r+c constant.
Approach Hinglish
Find empty cell. Try digits 1..9. Valid ho to place, solve rest, fail ho to undo.
Equation / Recurrence
backtrack cell by cell
class Solution {
public:
bool valid(vector<vector<char>>& b, int r, int c, char ch) {
for (int i = 0; i < 9; i++) {
if (b[r][i] == ch || b[i][c] == ch) return false;
int br = 3 * (r / 3) + i / 3;
int bc = 3 * (c / 3) + i % 3;
if (b[br][bc] == ch) return false;
}
return true;
}
bool solve(vector<vector<char>>& b) {
for (int r=0;r<9;r++) for (int c=0;c<9;c++) if (b[r][c]=='.') {
for (char ch='1'; ch<='9'; ch++) {
if (valid(b,r,c,ch)) {
b[r][c]=ch;
if (solve(b)) return true;
b[r][c]='.';
}
}
return false;
}
return true;
}
void solveSudoku(vector<vector<char>>& board) { solve(board); }
};
Complexity + Tips
Backtracking exponential but fine for 9x9.
Return bool because only one solution needed.
Equation / Recurrence
target = sum/k, fill buckets
class Solution {
public:
bool dfs(vector<int>& nums, vector<int>& bucket, int idx, int target) {
if (idx == [Link]()) return true;
int x = nums[idx];
for (int i = 0; i < [Link](); i++) {
if (bucket[i] + x > target) continue;
bucket[i] += x;
if (dfs(nums, bucket, idx + 1, target)) return true;
bucket[i] -= x;
if (bucket[i] == 0) break; // avoid symmetric empty buckets
}
return false;
}
bool canPartitionKSubsets(vector<int>& nums, int k) {
int sum = accumulate([Link](), [Link](), 0);
if (sum % k) return false;
sort([Link](), [Link]());
vector<int> bucket(k, 0);
return dfs(nums, bucket, 0, sum / k);
}
};
Complexity + Tips
Exponential, pruning important.
Sort descending = big stones first, search fast cut hota hai.
Approach Hinglish
Head ke baad wali list reverse ho jaye. Fir head ko end me attach karo.
Equation / Recurrence
reverse(head)=newHead of reverse(head->next)
Complexity + Tips
Time O(n), stack O(n).
Dry run 1->2->3. Returning pe 3->2, then 2->1.
Equation / Recurrence
merge(a,b)=min head + merge(rest,other)
Complexity + Tips
Time O(n+m), stack O(n+m).
Approach Hinglish
First two nodes swap karo. Baaki list recursively swap.
Equation / Recurrence
newHead=head->next; head->next=swap(rest)
Complexity + Tips
Time O(n), stack O(n).
Pointer rewiring carefully karo.
Approach Hinglish
Preorder: root-left-right. Inorder: left-root-right. Postorder: left-right-root.
Equation / Recurrence
Base: null return
Complexity + Tips
Time O(n), stack O(height).
Tree recursion ka hello-world.
Approach Hinglish
Depth = 1 + max(left depth, right depth).
Equation / Recurrence
D(node)=1+max(D(left),D(right)), D(null)=0
Complexity + Tips
Time O(n), stack O(h).
Approach Hinglish
At every node, candidate diameter = leftHeight + rightHeight. Height return karo, global best update karo.
Equation / Recurrence
height=1+max(L,R), diameter=max(diameter,L+R)
class Solution {
public:
int best = 0;
int height(TreeNode* root) {
if (!root) return 0;
int L = height(root->left);
int R = height(root->right);
best = max(best, L + R);
return 1 + max(L, R);
}
int diameterOfBinaryTree(TreeNode* root) {
height(root);
return best;
}
};
Approach Hinglish
Postorder recursion. Height return karo. Agar subtree unbalanced to -1 return.
Equation / Recurrence
height or -1 sentinel
class Solution {
public:
int check(TreeNode* root) {
if (!root) return 0;
int L = check(root->left); if (L == -1) return -1;
int R = check(root->right); if (R == -1) return -1;
if (abs(L - R) > 1) return -1;
return 1 + max(L, R);
}
bool isBalanced(TreeNode* root) {
return check(root) != -1;
}
};
Complexity + Tips
Time O(n), stack O(h).
Avoid O(n^2) by computing height once.
Approach Hinglish
At node, target se node value subtract karo. Leaf pe check target == val.
Equation / Recurrence
has(node,sum)=has(left,sum-val)||has(right,sum-val)
Complexity + Tips
Time O(n), stack O(h).
Approach Hinglish
Current path maintain karo. Leaf valid ho to answer me copy. Return pe pop.
Equation / Recurrence
class Solution {
public:
vector<vector<int>> ans;
void dfs(TreeNode* root, int target, vector<int>& path) {
if (!root) return;
path.push_back(root->val);
if (!root->left && !root->right && target == root->val) ans.push_back(path);
dfs(root->left, target - root->val, path);
dfs(root->right, target - root->val, path);
path.pop_back();
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<int> path;
dfs(root, targetSum, path);
return ans;
}
};
Complexity + Tips
Time O(n*h) for path copies, stack O(h).
Tree path problem = push, recurse, pop.
Approach Hinglish
If current null/p/q return current. Left and right search. Dono side non-null to current LCA.
Equation / Recurrence
return node pointer signals found
Complexity + Tips
Time O(n), stack O(h).
Return value itself carries information.
Approach Hinglish
Min and max allowed range carry karo.
Equation / Recurrence
low < node->val < high
Complexity + Tips
Time O(n), stack O(h).
Local child compare is not enough. Range carry karo.
Approach Hinglish
Array ko half me divide karo, dono halves sort karo, merge karo.
Equation / Recurrence
T(n)=2T(n/2)+O(n) -> O(n log n)
Complexity + Tips
Time O(n log n), space O(n), stack O(log n).
Approach Hinglish
Partition pivot ko correct place pe laata hai. Then left/right sort.
Equation / Recurrence
Average T(n)=2T(n/2)+O(n), worst O(n^2)
Complexity + Tips
Average O(n log n), worst O(n^2), stack average O(log n).
Approach Hinglish
Merge sort ke during left and right sorted hote hain, so counting fast hoti hai.
Equation / Recurrence
Count left + count right + count cross
Complexity + Tips
Time O(n log n), space depends on merge.
Sorted halves allow two pointer count.
Approach Hinglish
Last move 1 step ya 2 step. So ways(n)=ways(n-1)+ways(n-2).
Equation / Recurrence
W(n)=W(n-1)+W(n-2)
int climbStairs(int n) {
vector<int> memo(n + 1, -1);
function<int(int)> f = [&](int k) -> int {
if (k <= 1) return 1;
if (memo[k] != -1) return memo[k];
return memo[k] = f(k - 1) + f(k - 2);
};
return f(n);
}
Complexity + Tips
Approach Hinglish
At index i: rob current and jump i+2, or skip current and go i+1.
Equation / Recurrence
f(i)=max(nums[i]+f(i+2), f(i+1))
Complexity + Tips
Time O(n), stack O(n).
Choice recursion: take vs skip.
Approach Hinglish
At amount rem, try every coin. Minimum of 1+solve(rem-coin).
Equation / Recurrence
f(rem)=min(1+f(rem-c))
Complexity + Tips
Time O(amount*coins), stack O(amount).
INF use karo, INT_MAX+1 overflow na ho.
// B. For-loop Combination
void dfs(int start) {
save_if_needed();
for (int i = start; i < n; i++) {
if (i > start && a[i] == a[i-1]) continue; // duplicates
choose(i);
dfs(i + 1);
undo(i);
}
}
// D. Grid DFS
void dfs(int r,int c) {
if (out || blocked || visited) return;
visited = true;
for (4 directions) dfs(nr,nc);
}
// E. Tree Recursion
int solve(TreeNode* root) {
if (!root) return base;