Tip 1: Try solving DSA questions using pen and paper first.
Tip 2: Study basic data structures like arrays, strings, linked lists, etc.
Tip 3: Create your resume based on genuine projects.
Tip 1: Add as many projects as possible.
Tip 2: Add genuine projects.
It was a coding and MCQ round consisting of technical questions on different subjects such as DBMS, OOPS, and Operating Systems. The round lasted for 2 hours, with the first 60 minutes allocated for MCQs and the next 60 minutes for 2 coding questions.



Given an array of N integers and an integer K, find the number of pairs of elements in the array whose sum is equal to K.
Here's a step-by-step approach to solving the problem of finding the number of pairs of elements in an array whose sum is equal to a given value K:
1. **Create a dictionary to store seen elements and their frequencies:**
- Initialize an empty dictionary to store the elements you've seen along with the number of times you've seen them. We'll use this dictionary to efficiently track if a complement (the number needed to reach K) exists for a current element.
2. **Iterate through the array:**
- Loop through each element (let's call it `num`) in the array.
3. **Calculate the complement:**
- Subtract the current element (`num`) from the target value (K) to find the complement (`complement`). This complement is the number you need to find in the array to make a pair that adds up to K.
4. **Check if the complement exists in the dictionary:**
- Look up the `complement` in the dictionary.
- If the `complement` exists in the dictionary:
- This means you've already seen an element that can be paired with the current element to reach K.
- Increment a counter variable by the number of times you've seen the `complement` (which is stored in the dictionary value). This represents the number of pairs you've found that include the `complement`.
- If the `complement` doesn't exist in the dictionary:
- Do nothing, as you haven't found a pair for the current element yet.
5. **Add the current element to the dictionary:**
- Add the current element (`num`) to the dictionary as a key.
- If the element already exists in the dictionary, increment its value by 1 (representing that you've seen this element one more time).
- If the element is not present in the dictionary, add it with a value of 1 (signifying you've seen it for the first time).
6. **Return the count of pairs:**
- After iterating through the entire array, the counter variable will hold the total number of pairs you've found whose sum is equal to K.
- Return this count as the solution.
This approach uses a dictionary to efficiently keep track of seen elements and their frequencies. By checking if the complement exists in the dictionary, we can quickly determine if a pair exists for the current element.



Given three arrays sorted in increasing order. Find the elements that are common in all three arrays.
Here's a step-by-step approach to find elements common in three sorted arrays:
1. **Initialize pointers for each array:**
- Create three-pointers, `i`, `j`, and `k`, initially set to 0. These pointers will iterate through the first, second, and third arrays, respectively.
2. **Iterate while all pointers are within bounds:**
- Use a `while` loop that continues as long as all three-pointers `i`, `j`, and `k` are within the lengths of their respective arrays.
3. **Compare elements at current pointers:**
- Inside the loop, compare the elements pointed to by the current pointers:
- If the elements at all three-pointers (`arr1[i]`, `arr2[j]`, and `arr3[k]`) are equal, it means this element is common in all three arrays.
- Add this common element to a result list.
- Increment all three-pointers (`i`, `j`, and `k`) to move on to the next elements in the arrays.
4. **Handle unequal elements:**
- If the elements are not equal, identify the smallest element among the three-pointers.
- If `arr1[i]` is the smallest, it cannot be a common element since the other two arrays are sorted and have larger elements at their current positions. Increment `i` to move on to the next element in the first array.
- If `arr2[j]` is the smallest, increment `j` for the same reason.
- If `arr3[k]` is the smallest, increment `k`.
5. **Continue iterating:**
- The loop will continue iterating, comparing elements and moving pointers until all pointers reach the end of their arrays.
6. **Return the result list:**
- After the loop terminates, the result list will contain all the elements that were common in all three arrays.
- Return this result list as the solution.
This approach takes advantage of the sorted nature of the arrays. By comparing elements at the current pointers and strategically moving the smallest pointer, we can efficiently find the common elements without iterating through the entire array.
It was a one-hour round which was conducted in a physical mode where we were given pen and paper and we had to solve DSA questions while the invigilators were sitting in front of us and then we had to explain the solution to them then and there.



Given the head of a linked list and a number k, the task is to find the kth node from the end. If k is more than the number of nodes, then the output should be -1.
Here's the step-by-step approach to finding the kth node from the end of a linked list in Python without providing the code:
1. **Utilize two pointers:**
- We'll leverage two pointers in this approach: a slow pointer (`slow`) and a fast pointer (`fast`).
2. **Move the fast pointer k steps ahead:**
- Initialize `fast` to point to the head of the linked list.
- Iterate `k` steps forward with `fast` to position it at the kth node (or beyond the end if k is larger than the list length).
- If `k` is greater than the number of nodes, `fast` will become `None` after these steps. This indicates the target node doesn't exist, so you can return -1.
3. **Move both pointers together:**
- Once `fast` is positioned correctly, start moving both `slow` and `fast` pointers together, one step at a time.
- Since `fast` is already `k` nodes ahead, by the time `fast` reaches the end of the list (becomes `None`), `slow` will be pointing to the `k`th node from the end (if it exists).
4. **Handle k greater than list length:**
- If `fast` becomes `None` before `slow` starts moving (i.e., in step 2), it signifies `k` is greater than the number of nodes in the list. In this case, return -1.
5. **Return the node's data:**
- Once `fast` reaches the end (`None`), `slow` will be pointing to the `k`th node from the end (or the head if k is 1).
- The data of the node pointed to by `slow` is the desired output.
It was a one-hour round which was conducted in a physical mode where we were given pen and paper and we had to solve DSA questions while the invigilators were sitting in front of us and then we had to explain the solution to them then and there.



Given the head of a linked list, the task is to reverse this list.
Here's a step-by-step approach to reverse a linked list in Python:
1. **Iterative approach with three-pointers:**
- Use three pointers: `prev`, `curr`, and `next`.
- Initialize `prev` to None and `curr` to the head of the linked list.
2. **Iterate through the list:**
- Start a loop that continues as long as `curr` is not None.
3. **Reverse the link:**
- Inside the loop, store the next node (`next`) after the current node (`curr`) using a temporary variable. This is because after reversing the link, you'll lose the reference to the next node.
- Set the `next` pointer of the current node (`curr`) to point to the previous node (`prev`). This effectively reverses the link between the current and previous nodes.
4. **Update pointers:**
- Move the `prev` pointer one step forward to point to the current node (`curr`).
- Move the `curr` pointer one step forward to point to the next node (which was stored in the temporary variable `next` earlier).
5. **Return the new head:**
- After the loop terminates (when `curr` becomes None), `prev` will be pointing to the new last node, which is now the head of the reversed list.
- Return `prev` as the new head of the reversed linked list.
This approach iteratively reverses the links between nodes, effectively reversing the entire list.


Given the head of a linked list, the task is to find the middle.
Here's a step-by-step approach to finding the middle node of a linked list in Python:
1. **Two-pointer approach:**
- Utilize two pointers in this approach: a slow pointer (`slow`) and a fast pointer (`fast`).
2. **Move pointers simultaneously:**
- Initialize both `slow` and `fast` to point to the head of the linked list.
3. **Iterate through the list:**
- Start a loop that continues as long as `fast` and `fast.next` are not None. This ensures you don't move the fast pointer beyond the end of the list.
4. **Increment pointers:**
- Inside the loop, iterate `slow` by one step and `fast` by two steps. This way, by the time `fast` reaches the end of the list (or the node next to the end if the list has odd elements), `slow` will be pointing to the middle node (or the second middle node for even elements).
5. **Return the middle node:**
- After the loop terminates, `slow` will be pointing to the middle node (or the second middle node).
- Return the data of the node pointed to by `slow`.
This approach takes advantage of the two pointers: slow moves one step at a time and fast moves two steps at a time. When the faster pointer reaches the end (or the second node from the end for even lists), the slower pointer will be in the middle.
It was a one-hour round which was conducted in a physical mode where we were given pen and paper and we had to solve DSA questions while the invigilators were sitting in front of us and then we had to explain the solution to them then and there.



Given a singly linked list and an integer x.Delete the xth node from the singly linked list.
Here's a step-by-step approach to delete the xth node from a singly linked list in Python:
1. **Handle empty list or deletion at position 0:**
- If the linked list is empty (head is None) or the position to delete is the head (x is 0), simply return None as there's no node to delete or the head needs to be removed.
2. **Create a dummy node (optional):**
- This step is optional but can simplify handling the case where you need to delete the head node. You can create a dummy node with a value of 0 and point its next pointer to the head of the original list. Then, operate on the dummy node's next pointer throughout the process.
3. **Iterate to the node before the one to be deleted:**
- Initialize a current pointer (`curr`) to point to the dummy node (or the head if not using a dummy).
- Iterate `curr` forward x-1 steps using a loop. This loop ensures `curr` points to the node right before the one you want to delete.
- If you reach the end of the list (curr.next is None) before iterating x-1 steps, it means x is greater than the number of nodes in the list. In this case, there's no node at that position to delete, so you can return the head (or the dummy node.next if using a dummy).
4. **Delete the node:**
- Assign the `next` pointer of the current node (`curr`) to point to the node after the one you want to delete (curr.next.next). This effectively skips the node you want to delete and connects the previous node to the one after it.
5. **Return the head (or dummy.next if using a dummy):**
- After deleting the node, return the head of the modified list (or the dummy node.next if you used a dummy).
By following these steps, you can traverse the linked list to the node before the one you want to delete and then modify the links to skip that node, effectively removing it from the list.



Given a linked list sorted in ascending order and an integer called data, insert data in the linked list such that the list remains sorted.
Here's a step-by-step approach to inserting a new node with data `data` into a sorted linked list in ascending order:
1. **Create a new node for the data:**
- Allocate memory for a new node and store the data (`data`) in its data field.
- Initialize the `next` pointer of the new node to None as it doesn't point to any other node yet.
2. **Handle empty list or insertion at the beginning:**
- If the head of the linked list is None (empty list), or the data to be inserted is less than the head's data:
- Set the `next` pointer of the new node to point to the current head (or None if the list was empty).
- Update the head of the linked list to point to the new node. This inserts the new node at the beginning of the list.
3. **Traverse the list to find the insertion position:**
- Initialize a current pointer (`curr`) to point to the head of the linked list.
- Iterate using a loop while the following conditions are met:
- The current node (`curr`) is not None (not at the end of the list).
- The next node (`curr.next`) exists (not the last node).
- The data of the next node (`curr.next.data`) is less than or equal to the data to be inserted (`data`).
- The loop will stop at the node where the next node's data is greater than the data to be inserted. This is the correct position to insert the new node.
4. **Insert the new node:**
- Set the `next` pointer of the new node to point to the current node's next node (`curr.next`).
- Set the `next` pointer of the current node (`curr`) to point to the new node.
5. **Return the head of the modified list:**
- After inserting the new node, the head of the linked list might have changed if the insertion happened at the beginning.
- Return the head of the modified linked list.
This approach iterates through the linked list to find the appropriate position for the new node based on its data value. Once the position is found, the new node is inserted between two existing nodes, maintaining the sorted order of the list.
This was an interview round where I had to give the approach for a linked list problem and explain them as well as basic HR questions.



Given a singly linked list having n nodes, your task is to remove every kth node from the linked list.
Here's a step-by-step approach to removing every kth node from a singly linked list in Python:
1. **Utilize two pointers:**
- We'll leverage two pointers in this approach: a `prev` pointer and a `curr` pointer.
2. **Handle empty list or k equal to 1:**
- If the head of the linked list is None (empty list) or k is equal to 1, it means you need to remove all nodes. Simply return None as the modified list.
3. **Iterate through the list:**
- Use a `while` loop that continues as long as `curr` is not None.
4. **Count nodes in a group:**
- Initialize a counter variable (`count`) to 0.
- Inside the loop, iterate `count` from 1 to `k`.
5. **Move the `curr` pointer k times (or until the end):**
- Within the inner loop iterating `count` times:
- Move the `curr` pointer one step forward for each iteration.
- If `curr` becomes None before reaching `k` steps, it means there aren't enough nodes left to form a group of `k`. Break out of the inner loop in this case.
6. **Handle removing the first node in a group:**
- If `count` is equal to `k` (after the inner loop), it signifies you've reached the end of a group where the `k`th node needs to be removed.
- If `prev` is None (meaning `curr` is the head), update the head to point to `curr.next` (effectively skipping the head node).
- Otherwise, set the `next` pointer of `prev` to point to `curr.next`, skipping the `k`th node in the current group.
7. **Update `prev` for the next group:**
- Set `prev` to point to the current node (`curr`). This `prev` will be used for potential deletion in the next group.
8. **Return the modified head:**
- After the outer loop terminates, the head of the modified list might have changed if the first node was removed.
- Return the head of the linked list after removing every `k`th node.
This approach iterates through the linked list in groups of `k` nodes. Within each group, it identifies the `k`th node and removes it by adjusting the links between the previous and next nodes. It also handles the special case of removing the head node if necessary.

Here's your problem of the day
Solving this problem will increase your chance to get selected in this company
What is recursion?