0% found this document useful (0 votes)
14 views37 pages

DSA Notepad

The document provides a comprehensive guide on various data structures and algorithms, focusing primarily on linked lists, binary trees, and dynamic programming techniques. It includes detailed explanations and implementations for tasks such as detecting cycles in linked lists, performing tree traversals, and solving common dynamic programming problems like the longest increasing subsequence and coin change. Additionally, it references various online resources for further exploration of the topics discussed.

Uploaded by

aurangozeb9
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views37 pages

DSA Notepad

The document provides a comprehensive guide on various data structures and algorithms, focusing primarily on linked lists, binary trees, and dynamic programming techniques. It includes detailed explanations and implementations for tasks such as detecting cycles in linked lists, performing tree traversals, and solving common dynamic programming problems like the longest increasing subsequence and coin change. Additionally, it references various online resources for further exploration of the topics discussed.

Uploaded by

aurangozeb9
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

—------------------------------------------------------------------------------------

DSA Notepad
—------------------------------------------------------------------------------------

1. Design linked list : main task was to make the structure


Struct Node {
Int data;
Node *next;
};
Node *head;
Node *tail;
Int size;

2. Linked list cycle: fast and slow pointers, in case of a cycle, the fast pointer meets the
slow pointer, but if there is no cycle, then the fast pointer ends its journey. Always take care of
the base condition (head == NULL).

3. Linked list cycle 2 (detect the starting point of the cycle in the linked list): use slow
and fast pointer to check whether they are meeting or not, if NO, then there is no cycle, if YES,
then take start = head and the slow pointer, do start = start -> next and slow = slow -> next,
wherever they will meet, that node will be the starting point of the cycle.

We can also use hashmap for this (but this will require O(N) space.

4. Intersection of 2 linked lists: we can use a brute force algorithm, we can also use the
hashmap (but it takes extra space complexity)
More optimized approach is using the 2 pointer method: count length1 and length2, now
do (length2 - length1), move the pointer of length2 by the distance length2 - length1, now
simultaneously , move both the pointers, wherever they meet, is the intersection of the
linked lists.

5. Deleting the kth node from the end: Take 2 pointers, progress the first one by k
distance, and then progress both the pointers simultaneously till the second pointer reaches
NULL or is pointing to NULL.

6. Reverse linked list: Iterative approach , O(n) method, take 2-3 pointers and then it will
be easy.

7. Palindrome Linked list: first find out the midpoint of the list by using slow pointers and
fast pointers -> when fast -> next == NULL OR fast -> next -> next == NULL, then stop the
interaction ,and the position of the slow pointer will be the mid point. Break the list from the
midpoint, reverse the second half of the list and check the palindrome by traversing through the
first half and the second reversed half.

8. Flatten the doubly linked list: using 3 pointers: *ptr, *runner, *temp, we can solve this
problem beautifully in O(n) time.
https://leetcode.com/explore/learn/card/linked-list/213/conclusion/1225/

9. Target sum: counting the number of subsets with sum = k;


Base case: if (nums[0] == 0) {dp[0][0] = 2;} else {dp[0][0] = 1;}
if (nums [0] != 0 && nums[0] <= k) {dp[0][nums[0] = 1;}

https://leetcode.com/explore/learn/card/queue-stack/232/practical-application-stack/1389

10. Binary tree inorder traversal (Iterative approach): use stack to do it.

https://leetcode.com/explore/learn/card/queue-stack/232/practical-application-stack/1383/

11. Decode String: use 2 stacks to solve the problem.


Maintain 4 variables, curr_str, cur_num, prev_str, prev_num.

If the character is an alphabet, just append it to the curr_str.

If the character is an integer, then do curr_num = curr_num*10 + integer

If the character is ‘[‘, then push curr_str to the stack1 and cur_num to stack2, reinitialize
curr_str = “” and curr_num = 0;

If the character is ‘]’, then pop prev_num and prev_str, apply the formula curr_str =
prev_str + prev_num* curr_str.

Finally return curr_str as the final answer.

12. Binary tree preorder/inorder/postorder traversal (recursive) : it's easy , we can do it

13. Binary tree preorder/inorder/postorder traversal (iterative):

https://leetcode.com/submissions/detail/696712028/ (preorder)
While (root || !s.empty()) : always start with this.
Preorder: if root is not NULL , we push root into the vector, now if root -> right is not
null, we push it into the stack and make root = root -> left.

If root == NULL, then root = s.top(), s.pop().

Inorder: do root -> left until root is NULL, then take the topmost node in the stack, push
its value in the vector, then do root = s.top() -> right and s.pop() and continue the same
process.
https://leetcode.com/submissions/detail/696711265/

Postorder: do root -> left until root is NULL, now take the topmost element of the stack
and check its right, if its right is not NULL, then assign root = s.top() -> right and
continue the process. But if the s.top() -> right == NULL, then we take temp = s.top();
s.pop(), push the value of temp in the vector and now run a while loop :

while (!s.empty() && s.top() -> right == temp) {


temp = s.top();
s.pop();
v.push_back(temp -> val);
}

https://leetcode.com/submissions/detail/696725964/

14. Symmetric Tree: we use 2 queues here, one condition to check is that if both left and
right are NULL, we do continue, if one of them is NULL, we return false, and rest toh we can do
it easily by using q1 and q2.

15. Construct the binary tree from inorder and postorder, inorder and preorder: we
can do it easily using recursion by considering 4 pointers: is, ie, ps, pe.
If (is > ie) return NULL;

16. Populating the next right pointers in a balanced binary tree:


while (start != NULL && start -> left != NULL) {
node -> left -> next = node -> right;

if (node -> next == NULL) {


node -> right -> next = NULL;
start = start -> left;
node = start;
continue;
}
else {
node -> right -> next = node -> next -> left;
node = node -> next;
}
}
17. Populating next right pointers 2: Use of head , temp and the dummy nodes.

while (head != NULL) {


Node *dummy = new Node();
Node *temp = new Node ();
temp -> next = dummy;

while (head != NULL) {


if (head -> left != NULL) {
temp -> next -> next = head -> left;
temp -> next = head -> left;
}
if (head -> right != NULL) {
temp -> next -> next = head -> right;
temp -> next = head -> right;
}
head = head -> next;

}
temp -> next -> next = NULL;
head = dummy -> next;
temp -> next = dummy;
}

18. Lowest Common ancestor in a binary tree: very simple recursive solution can be
written. Call on left , call on right. If left and right , both are NULL, return NULL, if any one of
them is NULL, return the not NULL value, if both of them are not NULL, return the root.

19. Isvalid BST:


TreeNode *prev = NULL;

bool isValidBST(TreeNode* root) {


if (root == NULL) return true;

if (isValidBST(root -> left) == false) {


return false;
}

if (prev != NULL && root -> val <= prev -> val) {
return false;
}
prev = root;
return isValidBST (root -> right);
}

We use the concept of the inorder traversal being sorted of a binary search tree. We just
check the current root’s value with the prev value.

20. Search in BST: a very simple implementation, if the value is less than the root’s value,
call on the left side, otherwise call on the right side.

21. Insert in BST: if the value to be inserted is less than the root’s value, call on the left hand
side, otherwise call on the right hand side.

22. Delete in BST: https://leetcode.com/submissions/detail/697358938/


Beautifully implemented this question.

23. Kth largest /smallest element in a stream: always use a priority queue, (max and min,
you can decide easily).

24. Is Balanced binary tree: we just add 2 lines of code in the famous find_height_of_tree
function. We say that if left_height || right_height is -1 , return -1, OR difference between them is
more than 1, then also return -1.
Beautifully done in O(N) time.

25. Convert sorted array into a BST: just use the concept of inorder traversal being sorted
in case of a binary search tree.

26. Find Duplicate Subtrees: if root == NULL, return an empty string, call on the left and
right side of the root.
String s = to_string(root -> val) + ‘x’ + left_string + ‘x’ + right_string;

Map[s] ++;
If (map[s] == 2) { pushback root in the vector}
return s;

27. Top K frequent elements using bucket sort: very beautifully implemented this
question:
https://leetcode.com/problems/top-k-frequent-elements/

28. Binary search : simple binary search (we have 3 templates), do remember.

29. Search in rotated sorted array:


// if the left half is sorted and the target lies in the left half, call on the left half.
// if the left half is sorted but the target doesnt lie in the left half, call on right half.
// if right half is sorted and the target value is in right half, call on right half.
// if right half is sorted , but the target value is not in right half, then call on left half.

For left half, r = mid - 1


For right half, l = mid + 1

30. Find the peak element using binary search: we assume nums[-1] and nums[n] =
negative infinity, and then we can easily do this question using binary search.

31. Find the min element in a rotated sorted array:


Key observation: minimum element always lies in the unsorted part of the array.
If both left and right are sorted, call on the left side.
Otherwise, call on the unsorted part.

32. Find the min element in a rotated sorted array containing duplicates:
Similar to the previous question.
If the nums[mid] < nums[end] , means that right half is sorted, call on the left half
If the nums[mid] > nums[end], right half is unsorted, so call on the right half
If nums[mid] == nums[end], r - - ;

33. Find the first and last position of the element in a sorted array
Use 2 functions:
First to calculate the first position of the element in the array
Second to calculate the last position of the element in the array

34. Find k closest elements:


Left = 0; right = n - k;
If (x - arr[mid] > arr[mid + k] - x) {left = mid + 1}
Else {right = mid}
35. Network delay time: We take the initial time to of each node to be infinity, and while
doing the bfs, if the time[x] = time[front] + weight of edge < time[x] , then update time[x] and
push the value into the queue, otherwise don’t push the value into the queue.

while (!q.empty()) {
int front = q.front();
q.pop();
for (auto x: m[front]) {
if (x == k) continue;
visited[x] = 1;
if (time[front] + m2[{front, x}] < time[x]) {
time[x] = time[front] + m2[{front, x}];
q.push(x);
}
}
}

36. Median of 2 sorted arrays:


Note that high = n1, and not n1 - 1.
https://leetcode.com/submissions/detail/699157857/

37. Find the kth smallest pair distance:


https://leetcode.com/problems/find-k-th-smallest-pair-distance/solution/

We use the two pointer technique to find the number of pairs whose difference is less
than equal to mid, if this count >= k, I call on the left hand side, otherwise I call on the
right hand side of the range.

Initial range is [0, nums[n-1] - nums[0]] provided I have sorted the array nums in
ascending order.

38. Split array largest sum:


https://leetcode.com/problems/split-array-largest-sum/

—---------------------------------------------------------------------------------------------------------------
DP Starts here
—---------------------------------------------------------------------------------------------------------------
39. Longest Increasing Subsequence:
3 approaches : first one is using the index and the prev index (coordinate change is also
done here). Index goes from n - 1 to 0, and previndex goes from index -1 to -1.
Dp[index][previndex] represents the length of the LIS ending at index with previndex

Next approach is the famous 1d DP approach, where dp[i] represents the length of the
LIS ending at i.
Time : O(n^2), Space: O(n)

The famous binary search approach. Do the lower bound for each element, if it is equal to
the end of the array, then push back the element, otherwise replace the element with the
found index by the lower bound function.

https://leetcode.com/submissions/detail/700501077/

40. Longest Common subsequence: it is easier to solve this in 1 based indexing.


Famous question, I know the approach, then also see the 1 based indexing below. Pick
not pick technique

41. Maximum product Subarray: curr_product and the max_product : 2 variables will be
there. As soon as we encounter a 0, we reinitialize curr_product to 1.
We do the same thing by traversing in the reverse order to take care of the odd number of
negative integers.
https://leetcode.com/problems/maximum-product-subarray/

42. Zeroes and Ones (0/1 knapsack): a good question. I used 3d dp to do this. A must revise
question. https://leetcode.com/problems/ones-and-zeroes/. Pick not pick technique

43. Coin change: Pick not pick technique and you will easily solve this question

44. Minimum path sum: Simple DP on grids.

45. Minimum cost to cut a stick : code is self explanatory


https://leetcode.com/problems/minimum-cost-to-cut-a-stick/
46. Partition equal subset sum: Base case becomes very very important. The famous pick
not pick technique. https://leetcode.com/problems/partition-equal-subset-sum/

47. House robber and House robber 2 : pick not pick technique. Space optimization can
also be done in these types of questions.
https://leetcode.com/problems/house-robber/
https://leetcode.com/submissions/detail/701297355/

48. Unique paths : without and with obstacles, famous grid questions.

49. Triangle : famous grid question. https://leetcode.com/submissions/detail/701313705/

50. Minimum path falling sum: standard grid question,


https://leetcode.com/problems/minimum-falling-path-sum/

51. Egg drop with 2 eggs and N floors: code is self explanatory
https://leetcode.com/problems/egg-drop-with-2-eggs-and-n-floors/

52. Cherry pickup 2: https://leetcode.com/problems/cherry-pickup-ii/

53. Subarray sum equals k: use prefix sum and a map to solve this question.

54. Coin change 2 problem: the pick not pick technique, unbounded knapsack
https://leetcode.com/problems/coin-change-2/

55. Minimum deletions to make string balanced: https://leetcode.com/problems/minimum-


deletions-to-make-string-balanced/

56. Shortest common supersequence: https://leetcode.com/problems/shortest-common-


supersequence/

Just make the dp array of the longest common subsequence, and then do something on dp
to get the desired string. 1 based indexing should be done.

57. Distinct subsequences: https://leetcode.com/problems/distinct-subsequences/


58. Edit distance: logic was simple, just concentrate on the base cases (do 1 based indexing
for easy code writing). https://leetcode.com/problems/edit-distance/
59. Wildcard matching: 1 based indexing for writing the base case, and the logic behind the
question is important.
https://leetcode.com/problems/wildcard-matching/

60. Buy and sell stock 2: dp[0][1] tells us about the maximum profit we can get by starting
from the 0th index provided we are allowed to buy it. https://leetcode.com/problems/best-time-
to-buy-and-sell-stock-ii/

61. Buy and sell stock 3: code is self explanatory.


https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/

62. Longest increasing path in a matrix: dp on graphs


https://leetcode.com/problems/longest-increasing-path-in-a-matrix/

63. Largest divisible subset: similar concept to that of the longest increasing subsequence,
but here, we also need to print the subset. For that we use the hash array and do the stuff as
explained by striver. https://leetcode.com/problems/largest-divisible-subset/

64. Longest string chain: similar concept as the longest increasing subsequence. Sort the
array of strings on the basis of length and then do the stuff asked in the question.
https://leetcode.com/problems/longest-string-chain/

65. Number of longest increasing subsequence:


Concept of count[i] telling me the number of increasing subsequences till index i having
length dp[i].

https://leetcode.com/problems/number-of-longest-increasing-subsequence/

66. Burst balloons: Partition dp, a superb question, we have to do it the reverse order.
https://leetcode.com/submissions/detail/704005840/

67. Palindrome partitioning 2: front partition dp.


https://www.codingninjas.com/codestudio/problems/palindrome-partitioning_873266
68. Partition array for the maximum sum: similar to the previous question, front partition
dp.

69. Largest Rectangle in a histogram: solved using 4 stacks, first 2 stacks for finding the
next right smaller element, and the rest 2 stacks for finding the next left smaller element.
https://leetcode.com/problems/largest-rectangle-in-histogram/

70. Palindromic substrings: dp[0][n-1] tells whether this is a palindrome or not, if dp[0] ==
dp[n-1] then call on dp[1][n-2] and so on.
https://leetcode.com/problems/palindromic-substrings/

71. Subset Sum equals to K: famous pick not pick technique


https://www.codingninjas.com/codestudio/problems/subset-sum-equal-to-k_1550954

72. Partition a set into 2 subsets such that the absolute difference between them is
minimum: we just calculate the total_sum of the array and now we have the dp which says 0/1
for every j = 0 -> total_sum. Traversing the last row of the dp, we can calculate the desired ans.
link

73. Number of subsets: link

74. 0/1 knapsack (values and weights, maxweight): link, base case is important.

75. Unbounded knapsack: base case important, link

76. Rod cutting problem: similar to the unbounded knapsack.

77. Longest common substring: link, dp[i][j = 1 + dp[i-1][j-1] if s1[i] = = s2[j]

78. Longest bitonic subsequence: similar concept as the longest increasing subsequence.
Link

79. Matrix chain multiplication: link


80. Evaluate Boolean expression to true: link, solve this (baki hai krna)

81. Longest Valid Parentheses: a very good question which uses both stacks and dp
(remembering the past). https://leetcode.com/problems/longest-valid-parentheses/

—------------------------------------------------------------------------------------------------------------------
Graph Starts here
—------------------------------------------------------------------------------------------------------------------

83. Cycle detection in undirected graph using BFS: link


Maintain the node and its parent, now while going through the adjacency list of the node, if we
find a x which is visited and is not equal to the node’s parent, then you say that cycle is detected.

84. Cycle detection in undirected graph using DFS: link


Same concept as used in BFS, we need to carry the node as well as its parent, and solve it
recursively in DFS.

85. Bipartite check using dfs and bfs: bipartite using bfs, bipartite using dfs
Graph is bipartite if we can color all the vertices with blue and green provided that no two
adjacent vertices have the same color.

86. Cycle detection in directed graph using dfs: https://leetcode.com/problems/course-


schedule/submissions/
We just maintain a visited array (values can be 0,1,2), if not visited, we call the dfs, if already
visited and the value is 2, then we say that there is a cycle, otherwise continue.

87. Topological sort using DFS: link


For a topological sort, directed acyclic graph is compulsory. We use a stack here to print the
topological sort of the graph. We just do the basic dfs and as soon as the dfs ends, we just push
the value of the node into the stack.

88. Topological sort using BFS (Kahn’s algorithm): link


Here, we use the queue data structure and an in-degree array. Whenever we get a node whose
indegree is zero, we just push that node into the queue. Whenever we pop the front from the
queue, pushback it into the the resultant vector.
89. Cycle detection in directed graph using BFS (Kahn’s algorithm): link
If we can get a topological sorted array, then we say that we have not detected a cycle, but if not,
then we have detected a cycle.

90. Russian Doll envelopes : a nice small variation of the LIS problem.
https://leetcode.com/problems/russian-doll-envelopes/

91. Shortest path in an undirected graph (with unit weights) with a source vertex: link
We can do this using simple BFS, by taking a normal level array, initialize the array with
infinity.

92. Shortest path in a directed acyclic graph with weights: First, we find the topological sort,
store it in the stack, then we take the distance array initialized with infinity, dist[src] = 0, now we
take the topmost element of the stack and do some stuff, and get the resultant distance array
which stores the shortest distance between the src and the vertex.
Link

93. Dijkstra Algorithm (shortest path in a weighted undirected graph): link


Use of min priority queue, initialize the distance array with infinity, and then push (0, source)
into the priority queue, and then do a kind of bfs traversal, whenever we get a weight of a vertex
to be smaller than its current weight, we update its weight and push the (weight, node) in the
priority queue.

94. Prim’s Algorithm for finding the MST: link


Use of minimum priority queue. Use of key array which is initialized to infinity, use of MST
array which is initialized to false, use of a parent array which is initialized to -1.
Parent[1] = -1;
Key[1] = 0;
pq.push(0, 1); //value and the node
Now run a while loop until the pq is empty. And do some stuff.

while (!pq.empty()) {
pair<int, int> front = pq.top();
pq.pop();
int u = front.second;
mst[u] = true;
for (auto x: adj[u]) {
int v = x[0];
int weight = x[1];
if (mst[v] == false && key[v] > weight) {
key[v] = weight;
parent[v] = u;
pq.push({key[v], v});
}
}
}

95. DSU:
Time complexity for finding the parent is almost constant. So for ‘m’ union operations, we
require O(m) time. In the above code, find parent function is written in a way such that it uses
path compression.

96. Kruskal Algorithm: link


Here, we store the edges and their weights in an array, and sort it according to the weights. Now
for every edge, we check if (u,v) belongs to the same component using the DSU data structure. If
yes, then this edge would create a cycle, so we don't add it to our MST, if not then we add it to
our MST.

97. Return all the bridges of a graph: link


Tin: time of insertion array
If (x == parent) continue;
Low [node] = min (low[node], tin[all the nodes which are visited], low[all the univisted nodes])

If (tin[node] < low[x]) {


We say that (node, x) is a bridge
}

98. Articulation point 1: link


Same concept as the bridges question. The only difference is that the
If (tin[node] <= low[x] && parent != -1) return the node;
If (parent == -1 && child > 1) return the source node.

99. Strongly connected components in a directed graph (Kosaraju’s algorithm): link


Firstly we find the topological sort of the given graph (store it in a stack using the simple dfs).
Now we take the transpose of the graph (meaning that if u -> v was an edge, we construct v -> u
edge). Now taking the topmost element of the stack, we do dfs in the transpose graph and print
the strongly connected components accordingly.

100. Bellman Ford Algorithm: link


For a directed weighted graph, we find the shortest distance between the source and all other
vertices. Time complexity is O(n*m). The only condition where we cannot use the bellman ford
algorithm is when we get a negative cycle.
Algorithm: Relax all the edges (n - 1) number of times, and the final distance array will contain
the shortest distances. But if we do the relaxation again and if we find more decrease in the
distance array, then we can say that there exists a negative cycle, because Bellman Ford says that
after (N-1) relaxations, we always get the shortest paths.

Todays Questions (27/05/2022)


Link Link2 Link3
Link4 (revise this : good question: hamiltonian path: explore all the paths by visiting the node
and then un-visiting the node, maintain a count)
Link5 Link6

Circle of strings : to do list

Link7 Link8

Maximum Bipartite matching: to do list

Link9 Link10 Link11

Link12 (revise this question, similar concept to that of the hamiltonian path, visit and unvisit
concept)

Link13
Link14 (Revise good question)

Todays Questions (28/05/2022):

Link1 Link2 Link3


Link4 (good question revise)

Link5 Link6 Link7 Link8 Link9 Link10 Link11

Link12 (revise this , good question)

Todays Questions (29/05/2022):

Link1 Link2 (good question revise) Link3 Link4

Link5 (good question revise -> dijkstra algorithm)

Link6 Link7 Link8

Link9

Link10 (a very good question , do revise this)

Link11
Link12 (Tarjan’s algorithm for finding the strongly connected components)

Link13 (a must revise question, visited and unvisited concept used again)

—------------------------------------------------------------------------------------------------------------------
Binary Trees and BST Starts here
—-------------------------------------------------------------------------------------------------
Basic Definitions:

Full binary tree: A binary tree in which each node has either 0/2 children.

Complete binary tree: a binary tree in which every level is completely filled except for the last
level and the nodes in the last level are filled from the left most side.

Perfect binary tree: All the leaf nodes are at the same level.

Degenerate binary tree: It is basically a skew tree. A linear tree resembling a linked list
Representation of the Binary tree:

Struct Node {
Int data;
Struct Node *left;
Struct Node *right;
}

Node (int val) {


Data = val;
Left = right = NULL;
}

Todays Questions (30 /05 /2022)

1. Diameter of a Tree (the same height function, but with that, pass a variable maxi with
reference where maxi = max (maxi, left + right + 1)

2. Maximum path sum : Similar to the concept of the diameter of the tree.
I calculate the max path sum for each node by doing the following:

int maxi = INT_MIN;

maxi = max (maxi, node -> val + left sum + right sum);
return node -> val + max(left sum , right sum);

3. same tree
4. Zig Zag traversal

5. Boundary traversal : First do the left boundary traversal, as soon as we encounter a leaf
node, stop it.
Then print all the leaf nodes using the preorder / inorder traversal…and then take the right
boundary (reverse it and then print it).

6. Vertical order traversal : A good question (should be revised)

7. Top view of BT: Same to same as the vertical order traversal


8. Bottom view of BT: Here, we do the level order traversal. We take a queue <node, col>
and do the bfs. Whenever we pop the element from the queue, we update
the map <col, nodevalue> m, by m[col] = node -> data.

9. Right view of the BT: same concept as the bottom view, the only difference is that here,
we deal in row instead of col as was the case in bottom view

10. Print the path from the root to the node: A good question, do revise.

11. Maximum width of BT: A very good question.


Used the concept that if the node is having index i, then its left child will have 2*i + 1
and the right child will have 2*i + 2 (in case of 0 based indexing). In case of 1 based
indexing, we have 2*i and 2*i + 1.
Here, to avoid the integer overflow, we take a long long int and do some smart trick to
solve the question.

Today’s Questions (31/05/2022)

1. Children sum property in binary tree : Good question, do revise


If the summation of the childs is more than the root, update the root, else update both the
child’s value to the root’s value.

2. Print all nodes at distance k from a target node: We store the parent of each node in a
hashmap. Then we do the dfs traversal (on the left, on the right, on the parent). We also keep a
visited hashmap so that the dfs does not visit the already visited node.

3. Time taken to burn the tree: Similar concept as the previous question, you need to store
the parent in a hashmap.
4. Count nodes in a complete BT: If the left and the right height is the same, then we just
return pow(2,h) - 1. Otherwise we return 1 + count(left) + count (right).

5. Serialize and Deserialize a BT: method is simple, we use a queue.


We also use stringstream s(data) and getline (s, str, ‘,’).

6. Morris inorder traversal: Beautifully implemented, a must revise question and do it


yourself as well.

Today's Task (01/06/2022)


1. Ceil of BST: if (x < root’s val), call on left, if left is -1, return root, else return left..
if (x > root’s val) return right.

2. Floor in BST: exactly opposite to that of the Ceil of BST.

3. kth smallest element in a BST:

4. Construct binary tree from preorder traversal: 2 approaches: 1 is to make the binary
search tree from preorder and inorder traversal (O(nlogn) time).

Another O(n) approach could be to use the upper bound. Initially the bound is
INT_MAX. If the counter == n, return NULL, OR, if preorder[counter] > bound, return
NULL.
While calling on left, bound is updated to the root value
While calling on the right, the bound remains the same.
Pass the counter i by reference.

5. Inorder successor of BST: similar concept as the ceil of a BST

6. BST iterator: This can be done using a stack and in O(h) space complexity

7. Two sum in a BST: We use the next and before concept here. For next, we go to the left
left left and store it in the stack. Now we take the topmost element of the stack and call the same
function for (s.top() -> right).
For before, we go to right right right and store it in the stack, then we take the topmost
element and call the same function for s.top() -> left.

8. Recover BInary search tree: We have done the O(n) time complexity and O(1) space
complexity. Here, while we are doing the inorder traversal, we take care of the adjacent
elements, 2 cases are there : 1 violation or 2 violations.

9. Largest BST in BT: very very important question

Today's Task (02/06/2022)


1. Mirror of a BT

2. Array to BST

3. Largest value in each level

4. Maximum gcd of siblings of a BT

5. kth largest element in a BST: We don't need to always store the inorder traversal in an
array, instead we can maintain a counter. This question is an example of that implementation, do
revise.

6. Check if a subtree: We use the famous strings method here, left + “X” + root->val + “X”
+ right

7. Single valued subtree: Used the method told by sanskar (using map)

8. Unique BST's

9. Construct binary tree from parent aray

10. Preorder traversal and BST: A must revise question, done using stacks.
First initialize the root = INT_MIN, now run a for loop over the preorder array, while
stack is not empty and the preorder[i] > the topmost element, make the root equal to the
topmost element and pop, else if pre order[i] < root, then return false, else push(pre
order[i]) into the stack.

11. Consturct Tree from Preorder traversal:

12. Minimum distance between 2 given nodes of a binary tree: Used the LCA concept, the
beautiful concept of parent and visited was giving runtime error on last test cases, I don't know
why.
13. Maximum sum from root to leaf

14. odd even level difference

15. Ancestors in a BT

16. Remove BST's outside given range: I used the iterative inorder traversal as it takes lesser
time as compared to the recursive method.

17. Sum Tree: Again used the method of map , told by sanskar

18. BST to greater sum tree

19. BST to max heap: The post order traversal of the max heap is sorted.

20. Clone a binary tree: I take a map from tree to new tree and solve this question.

21. Maximum sum of non-adjacent nodes: I use the map thing again, told by sanskar

22. Extreme nodes in alternate order

23. Connect nodes at same level: same as populating next right pointers (memorize this, very
important).

24. Nodes at given distance in binary tree

25. Sorted Linked List to BST: Used the technique of slow and fast pointers to find out the
middle element, beautifully implemented.

Today's Task (03/06/2022)


1. Binary Tree to Doubly linked list: There is always no need to store the whole inorder
traversal in an array, instead we can always use the concept of prev for the inorder
traversal.

To do list :

2. K-sum paths: a must revise question, we use a hashmap, initially m[0] = 1, now we take
the curr_sum and the target as parameters in the function call,

if (m.count(cur_sum - target)) , update the answer with the frequency of curr_sum -


target, call on left and right, at last do m[curr_sum ] - -;

3. Number of turns in binary tree: First find the LCA, then assign each node a column, then
find the path from LCA to p and q, now according to the path, find the number of changes in the
direction.

4. Merge two BST's: First find the inorder of both the BST’s, and then merge them into the
resultant array.

—------------------------------------------------------------------------------------------------------------------
SDE Sheet remaining Questions starts here
---------------------------------------------------------------------------------------------------------------------

Check out the to do list in the sheet itself as well as on leetcode (there are a few problems which
I have to do)

Day 1: done Day 17: done


Day 2: done Day 18: done
Day 3: done Day 19: done
Day 4: done Day 20: done
Day 5: done Day 21: done
Day 6: done Day 22: done
Day 7: done Day 23: done
Day 8: done Day 24: done
Day 11: done Day 25: done
Day 12: done Day 26: done
Day 13: done Day 27:
Day 14: done Day 10: done
Day 15: done
Day 16: done
Today's Task (04/06/2022)

1. Set matrix zeroes: Space optimized from O(n + m) to O(1).


Here, we use the first row and the first col as the 2 dummy arrays.
And 2 variables : is first row zero and is first col zero
We traverse from i : 1 -> n and j : 1 -> m, and if the matrix[i][j] is 0, we mark the
corresponding ith and the jth index as 0 in the 2 dummy arrays.

2. Next permutation: For every element, find the minimum element which is greater than it
on the right hand side.

3. Sort colors: Used the 2 pointer method

4. Merge intervals: Used the custom sort to sort the given array and then the logic was
simple
5. Merge sorted array: I traverse from the back side, and compare the last elements , as the 2
given arrays are sorted.

6. Repeating and missing number: Here, we apply the formula of summation N and
summation N square.

7. Count inversions: Used the concept of merge sort here, a very good question.

8. Majority element: Application of Moore's voting algorithm, please see the intuition
behind this also in the striver video. Link\

9. Majority element (> N/3 times): Boyre Moore’s voting algorithm, here we take num1,
num2, count1, count2. At last we have 2 numbers num1 and num2 but we are not sure about
them being the majority element , so we traverse the array and find their count, if it is more than
N/3, then I push_back it into the resultant array.

10. Inverse pairs (nums[i] > 2*nums[j]): A very good question, again using the concept of
merge sort.
Today's Task (05/06/2022)

1. 4sum problem: We can do the O(n^3) method plus using the hashset (using the two
pointer method), but this takes O(n) space complexity. To reduce the space complexity,
we can maintain previous elements.

2. Longest consecutive sequence: Brute approach is to sort and then a linear traversal will
give you the answer.
The second optimized approach is to use the unordered_map, for every element in the array, if
element - 1 exists in the map, do nothing, if it doesn't, then check till how far the elements exist
in the map by incrementing the value.

3. Count subarrays with given XOR: we know the xor till index i, before i , we have stored
all the xor’s in a hashmap, now if till index i , the xor is xor, then we will check if there exists a
xor with the value = (xor ^ x), if yes, then update the answer with the frequency of it in the
hashmap.

4. Flattening a linked list: First merge the last 2 linked lists using the striver method of
merging, very easy.
Merger last two, then again last two, and continue doing so, can be done easily using
recursion.

Today's Task (06/06/2022)

1. Trapping rainwater system


for every index i, we have to calculate the rightmost max and the leftmost max, and
the, answer will be minimum(rightmax[i], leftmax[i]) - height[i];

Better approach is to use the two pointer method -> O(1) space and O(n) time
Int left = 0; int right = n - 1; int leftmax = 0; int rightmax = 0;

2. Remove duplicates from the sorted array: Think of swaps

3. N meetings in one room: sort the vector pair according to the second element, and then
observe that we will always consider the first meeting and then apply greedy, a very simple one
4. Minimum platforms: Use of a multiset here (O(nlogn) time + O(n) space).

Optimized approach : O(nlogn) time + O(1) space

First of all, sort both the arrays, now take two pointers i and j
While (i < n), if the arrival[i] <= departure[j], increment platforms
Else decrement platforms.

While incrementing the platforms, maxi = max (maxi, platforms)


At last, return the maxi (the maximum number of platforms)

5. Nth root of m: Here, we do a binary search having a search space from [1, m].
If the mid^n > m, r = mid, otherwise l = mid, do it till (r - l) > -1e6.

6. Matrix median: Binary search over the search space (1, 1e5), if the number of elements
less than equal to mid is less than (n*m)/2, call on the left side, otherwise call on the right side.
While (l < r) return l;

7. Single element in a sorted array: Using binary search we can do it in O(logN).


If (nums[mid] != nums[mid + 1] && mid is even, call on left side, else call on right side.
If (nums[mid] == nums[mid + 1] && mid is odd, call on right side, else call on left side.

8. kth element of two sorted arrays: Time complexity is O(log(min(N, M))

Similar approach as the median of two sorted arrays.


We again use the low, high, cut1, cut2, left1, left2
Here, low = max (0, k - max(n,m)) , high = min (k, min(n,m))

Cut1 = (low + high)/2 , cut2 = k - cut1

If (left1 <= right2 && left2 <= right1) return max(left1, left2)

Rest all remains the same

9. Allocate books: Similar question as the famous binary search problem of subarrays <= m
Today's Task (07/06/2022)
1. Kth largest element in an array: Whenever kth largest comes, always use a minimum
priority queue, takes Nlogk time.

2. find median from data stream: Done using 2 priority queues (min and max).

3. merge k sorted arrays: use of priority queue here, make a triplet (element, array index,
index) and u can solve it easily.

4. Implement stack using 1 queue : can do it easily

5. Implement queue using stacks : We will have to do it by using 2 stacks, amortized O(1)
method, push into s1,
If s2 is not empty, then the top most element of s2 is the top, otherwise pop all elements
from s1 and push it into s2, and now whichever is the topmost element on the stack s2,
that is the answer.

6. Next greater element: If the question is asked for a circular array, u dont have to do
anything, just simply append the elements of the array to the right, and find the next greater
element for each index, no need to make extra space for appending the array, you can traverse
your i from 0 to 2n - 1, and then apply the formula i % n.

7. Sort a stack: a good question done using recursion, do revise

8. LRU cache: A must do question, used hashmaps and the doubly linked list.

9. Largest rectangle in a histogram: previously I had solved using 4 stacks, now did it using
2 stacks (each being a pair <int, int>).

Todays’ Task (08/06/2022)

1. Sliding window maximum: Used deque here, it allows push_back, push_front, pop_back,
pop_front. Done in O(n) time and O(k) space.

2. Maximum of minimums of every window size:


The question boils down to finding the next smaller element of the left and right side. By
doing this each element can say that I am the maximum for this much range, and then we
calculate the maximum for each window size.

3. The celebrity problem: Elimination approach using stacks.


Push all the indices in the stack, now take out the 2 topmost elements from the stack, and check
if M[u][v] == 1, then u cannot be the answer, else v cannot be the answer, eliminate the one
which can’t be the answer, push the other one inside the stack until the size of the stack becomes
1.

4. Longest palindromic substring: naive approach : O(N^3) time with no space

DP approach : O(N^2) time with O(N^2) space

Most efficient approach : O(N^2) time with no space


This approach says that for every index, I have to assume it to be the center of the
palindrome, and check for the left half and the right half, so in this way ,we can get the
maximum length palindrome for each index being the center. This was for an odd length
palindrome.

For even length, there will be two centers, so we will have to check for that.

Today’s Task (09/06/2022)

1. The Rabin carp algorithm: A very important algorithm for string matching using hashing

Int p = 31; int N = 1e5 + 3; int mod = 1e9 + 7


Precompute the vector of powers of size N
Now calculate the hash of the string s, and store it in the vector of size s.size() + 1;
Now calculate the hash value of the pattern string.
Now traverse through the string s, and check if the hash of the substr is equal to the hash
value of pattern or not.

Time complexity : O(m + n)

2. Longest prefix suffix: find the lps array for the string s of length n. This is the famous
KMP alogirthm’s first part where we find the lps for the string s.

3. Min characters to be added at front to make the string palindrome: This is nothing but to
find the lps of the string s + string (rev(s)).
Edge case: if the string is already a palindrome, just return 0, no need to find the lps.
Today’s Task (10/06/2022)

1. Job sequencing problem: we sort the array in the descending order based on the profit,
and we also make a deadline array initialized with -1, and then we can apply some greedy
technique and solve the problem using 2 for loops.

2. The egg dropping problem: Here, we have n floors and k eggs.

3. maximum sum increasing subsequence: Same concept as the longest increasing


subsequence, just adding one more condition:
Ans[i] < ans[j] + arr[i], then update the ans[i] = ans[j] + arr[i]

4. Find the duplicate number: used the concept of the slow and fast pointer, first we found
out the collision node, by moving the slow pointer by one step and the fast pointer by two
steps.Now we take the starting node and keep the slow pointer in tact, and then move both the
pointers simultaneously, wherever they will meet, will be the required answer (the starting of the
loop)

5. search a 2d matrix: 4 approaches : O(n*m), O(nlogm), O(n) + O(m), O(log(nm))

Today’s Task (11/06/2022)

1. Toppers of the class: You should know how to sort an object of a class/structure.

2. Magnets problem : Use binary search here, we are taking double, so whenever, absolute
value of left sum - right sum is less than 1e-6, return mid.

3. binary search ka subarrays ka question: do check the condition for l + 1 == r, very very
important.

4. Maximum sum rectangle: Do using the kedane’s algorithm and the prefix sum. Time :
O(n^3). We need to calculate the prefix sum column vise and then apply the kedan’s algorithm.

5. Longest increasing path in a matrix: a good question done on my own, do revise this
6. Minimum operations to reduce X to zero: we make a prefix array, we make a suffix array,
we invert the suffix array, and now we first of all find the x in prefix and suffix array by binary
search, after that I find the x - pref[i] in the suffix array accordingly.,

7. Count the number of substrings : the answer will be atmost (s, k) - atmost (s, k - 1).
Here utmost(s, k) will count the number of substrings having distinct characters at most k
using the sliding window technique, use 26 valued vector as it doesnt give TLE.

8. Check mirror in n - ary tree: A very simple question, can be done using map of stacks.
First iterate through the first array, push the nodes into the stack and then iterate through
the second array and check if the top most element of the stack is equal or not, if yes,
then pop and continue the same process.

9. Magic triplets: So here for every index i, I take a dp[i][1], dp[i][2], dp[i][3].
Here, dp[i][1] will be equal to 1 always,
We use the concept of the longest increasing subsequence length.
If (nums[i] > nums[j]) dp[i][2] ++;
Dp[i][3] += dp[j][2]

At last return the summation of dp[i][3] for all i from 0 to n - 1.

Today’s Task (12/06/2022)

1. Stock and buy sell: Valley and hill question, valley is a valley when arr[i] <= arr[i+1] &&
arr[i] < arr[i-1].
A hill is a hill when arr[i] >= arr[i-1] && arr[i] > arr[i+1].

2. Find missing and repeating number: First we find the repeating number by using the
property that all the numbers remainder with n will be the indices of the array (0 to n - 1).

Now, we take a variable x and assign it to the xor of all the elements of the array.
Again take xor of x with each element form 1 to n.
Now x ^ repeat will give us the missing number.

Today’s Task (13/06/2022)


1. minimum sum four sum subsequence: dp[i] tells us about the minimum sum subsequence
such that at least one element from every 4 consecutive integers is taken provided that we
take the arr[i].
Therefore, dp[i] = arr[i] + min (dp[i-1], dp[i-2], dp[i-3], dp[i-4]);
Finally , we return min (dp[n-1], dp[n-2], dp[n-3], dp[n-4])

2. Minimum number of jumps: We can always do the O(n^2) approach by using greedy.
But the optimized solution is to use O(n) time and O(1) space.
Use 3 variables: steps , jumps, maxreach
Initialize steps = arr[0] = maxreach, jumps = 1;
For (i = 0 -> n) {
Maxreach = max (maxreach , i + arr[i])
Steps –;
If (steps == 0) {
Jumps ++;
If (i >= maxreach) return -1;
Steps = maxreach - i;
}
}

3. Maximum number of zeroes and ones in a binary string: Just kadan’s algorithm (was
hidden inside)

4. count subsequences of type a^i, b^j, c^k: take three variables a = 0, ab = 0, abc = 0;
Now starting from the first occurrence of a, traverse the string, and perform the
following:
If you detect a, then a = 2*a + 1;
If you detect b, then ab = 2*ab + a;
If you detect c, then abc = 2*abc + ab;
Return abc;

5. Interleaved strings: a good dp question, done on my own

Today’s Task (14/06/2022)

1. Minimum steps to delete a string: A very good dp question.


Dp[i][j] tells that how many minimum number of steps is required to delete substring i,j.

2. Count digit groupings of a number: Written a recursive memoization solution, you should
know how to write these memoized solutions, very important.
In this question, there are two states, index and the sum, and then we have solved this
question.

3. Player with max score: A very important question.

We calculate the total sum of the array first, now we recursively find out the maximum
score that player 1 can get. If it is his chance, then return max(take first element or take
the last element) , if it is player 2’s chance, then return min (take first ele or take last ele)

While chance == 1, we add the nums[first] or nums[end], because we want to find the
score of player 1, but when chance == 2, we don't add anything.

4. Count palindromic subsequences: if s[i]== s[j], dp[i][j] = 1 + dp[i][j-1] + dp[i+1][j]


If (not equal) then dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+1][j-1]

5. Box stacking: First make triplets of (l,w,h) and push that into a new vector, now sort the
vector in the decreasing order of their base area, and then simply apply the concept of the LIS.
While making the vector, take l > w always for simplicity

6. Array partition: dp[i] says that whether we can have the ith element as the last element of
a partition or not. First sort the array, now for index i, find l = lower_bound(arr[i] - m), and h = i
- k; Now traversing between l and h, dp[i] = dp[i] | dp[j], if dp[i] is 1 , just break

At the end, return dp[N]

7. Longest zig-zag subsequence: first take all the unique elements of the vector, and then
just find all the valleys and hills, the sum of them will be the answer

8. Word wrap: return dp[0] at last


Here, dp[i] represents the minimum cost we can get if we start at i.
2 for loops will needed, one of i from n - 1 to 0 and other one for j from i to n - 1.
Do consider the case of not taking the spaces of the last line (when j + 1 == n)

Today’s Task (15/06/2022)

1. Print all permutations: A simple recursive backtracking question in which u need to swap
the elements and call for recursion.
2. N-Queen problem: first of all , create a board, and then try to place the queen for each
row and col, make a function if we can place the queen or not, if we can place, call recursion,
after recursion ends, remove the queen from there and continue forward.

3. Sudoku solver: you just have to return one solution, take care of that, otherwise the
solution will give TLE.

4. optimal strategy for a game: Understand it carefully, I take the first or the last element
and I take the minimum of the rest 2 recursive calls as the opponent is also playing optimally.
And after than I take the maximum of the first element picked answer and the last element
picked answer.

5. number of flowers in full bloom: simple upper bound and lower bound on start and end
array respectively.

6. Maximum trailing zeroes in a cornered path: We just have to find the power of 5 and
power of 2 in the product, and take the minimum of them, we can use the prefix sum technique
for this.

7. Longest path with different adjacent characters: For a particular node, the answer can be
the maximum size of the substrees or the sz[subtree(i)] + sz[substree(j)] + 1 provided both these
subtrees’s root don't share the same character with the node.

Today’s Task (16/06/2022)

1. Product of array except self: We can do the changes in the output array itself, but first
calculating the prefix product and then taking a variable suffix_product and changing the
output array accordingly.

2. Container with most water: Use the two pointer method, and solve the question easily

3. Basic calculator: We use a stack here, and for calculating the number, use the famous
formula of curr_num = curr_num * 10 + the digit.
If the operation is ‘+’, simply add the curr_num to the stack.
If the operation is ‘-’, then add -1*curr_num to the stack.
If the operation is ‘*’, then multiply the top most ele and the curr_num and then push the
result in the stack. Same goes for the divide operation.
4. Minimum window substring: Use the sliding window approach, and use vector to store
the frequency, don't use map , it gives TLE.

Today’s Task (18/06/2022)

1. search in a 2d matrix

2. kth smallest element in a sorted matrix: always use int mid = l + (r - l)/2, because it
doesnt give errors when using negative numbers.
This question involved doing the binary search over the range of numbers and for each
number we have to calculate the rank of the number.

Today’s Task (19/06/2022)

1. Implement trie (prefix tree): Use of classes here, do revise this, very very important
implementation, asked in DE Shaw interviews.

2. Flatten nested list iterator: Use of recursion here, if the list[j] is integer, then just
push_back it into the answer vector, else call recursion over the list[j] which is a list.

3. The Skyline Problem: A very good question.

We make a new vector ,in which we store, start_pos, height, s… and end_pos, height, e.
We sort this vector by using the custom sort.

3 edges cases has been considered here, its there in the code, see that

Then we use a multiset, for start, we insert the height into the multiset, if the max_val
changes, then push_back the answer in the ans vector.
For end, we erase the height from the vector, if the max_val changes, then push_back the
answer in the ans vector.

4. Word search 2: A very good implementation of tries here. A must revise question. Time
complexity using trie is O(nm) * O(nm).
5. Remvoe invalid parenthesis: In this question, we first calculate the minimum amount of
parenthesis to be removed by using a stack to reduce the time complexity, then it is a simple
recursive problem.

6. Regular expression matching: if s[i-1] == p[i-1] ; dp[i][j] = dp[i-1][j-1];

Rest conditions you can see in the code, self explanatory, not that difficult to understand.

Today’s Task (20/06/2022)

1. Prefix and suffix search: Logic is 100% correct, I dont know why it is giving TLE.

2. Binary tree cameras: 0 if not monitored, 1 if monitored, 2 if there is a camera,and then we


just have to look for some cases, and the question is done.

3. Count of small numbers after self: same concept as the inversion pairs in an array. Use
merge sort here

4. Maximum candies allocated to k children: A good binary question, I was not able to think
of the solution during the contest even after spending 45 minutes, binary search should not create
a problem bro. Do think of applying binary search on the answer as well.

5. Increasing triplet subsequence: we take 3 variables i, j, k , all initialized with value


INT_MAX. If nums[x] <= i, update i.
Else if nums[x] <= j, update j.
Else update k;

At the end, if k is not INT_MAX, return true, else return false.

Today’s Task (21/06/2022)

1. Count pyramids in a grid: dp[i][j] = min(dp[i + 1][j -1], dp[i + 1][j], dp[i + 1][j +1]) + 1/0
accordingly.

Today’s Task (25/06/2022)


1. Maximum xor of two numbers in an array: Trie OP. Represent the numbers in terms of
32 bit and store them in the trie, now for every number, we want to maximize the xor, so
look for the opposite bit, if we get it then it is well and good, but if we don't, then move
the same bit only in the trie.

—------------------------------------------------------------------------------------------------------------------
Google top interview questions starts here
—-------------------------------------------------------------------------------------------------

1. shortest unique prefix for each word: this is a simple trie question, you just have to create
another public member freq which stores the frequency of the prefixes. As soon as you
encounter a prefix with the frequency 1, you can say that this is gonna be the shortest
unique prefix for the particular word.

2. find the element occuring once when all other are appearing thrice: we have to do it using
bit manipulation, check each bit (0 to 31) for each number, and update their count based on the
setness of the bit (1 or 0). Finally, if we get a position of the bit, whose count is 3k + 1 and is set,
then we can add it to our final answer.

3. Generate binary string: A good recursive question, always try to understand what is
happening inside the recursive calls.

4. Number following a string: use a stack here, whenever we see a decreasing sign, push the
count into the stack and increase the count.
Whenever we see a increasing sign, push the count into the stack, print the stack and
empty it, count ++
After the while loop gets completed, you again need to push the count into the stack and
print it and empty it.

5. Minimum operations to convert array A into B: We just take out the elements from A
which are a part of B, and find the length of the LIS using the lower_bound approach, this LIS
will be the LCS between array A and B. and then, the problem is solved

6. Longest repeating subsequence: same as the LCS problem, just one more condition is
added , that, i != j when s1[i] == s2[j].
7. Non repeating numbers: do xor of all the elements, check the rightmost set bit, and now
distribute all the elements into 2 groups on the basis of them having this particular bit set or not
set. Beautifully done in O(n) time and O(1) space.

8. Modular exponentiation for large numbers: n -> n/2 -> n/4 and so on…..does it in
O(logn) time

9. Word Break (Trie): a good trie question, have to check each and every prefix of the given
string in the trie, a type of recursive solution
10. Maximum index: we store the prefix minimum and the suff maximum, and we can easily
solve this question in O(n) time.
TC : O(n) and Space: O(n)

11. Largest number in K swaps: simple backtracking question, try all swaps

12. kth smallest element in an array: The array contains distinct elements, I have used the
quick select algorithm from youtube only, the logic and code is 100% correct, I don't know why
it shows runtime error on test case 157.

13. check if 2 strings are k anagrams or not: counter array of size 26, string1 ++, string2 - -
And then , just a simple logic and you are done

14. Nth natural number: Here we have to find the answer from the numbers having base 9.
Base 9 means that the numbers will comprise of digits (0 - 8). For this we just have to follow the
same method of finding a binary representation of a number (that is base 2). Here it is base
9. The answer will be the reverse of the representation obtained.

15. circular tour: use two pointers here, i and j, for any index, if we get a balance to be
negative, then start from the very next index, and continue to do so until we get the
vis == n or count < 2*n. Because every index will be visited at most twice in cases where
we don't get any answer.

You might also like