Skip to content

Sorting, Searching and Dynamic Programming Interview Questions for C Programming with DSA

25 Sorting, Searching and Dynamic Programming questions with answers for c programming with dsa roles — 7 easy, 11 medium, 7 hard.

About Sorting, Searching and Dynamic Programming

Finish with core algorithm design. Learn Big O analysis, binary search and its variants, quicksort, merge sort, heap sort and counting sort, recursion and backtracking, greedy algorithms and dynamic programming problems such as knapsack, coin change and longest common subsequence, with tips to explain complexity clearly in interviews.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01
Save to ▾
Show answer
Big O describes how an algorithm's time or memory grows as input size grows, ignoring constants and lower terms. Common classes are O(1), O(log n), O(n), O(n log n), O(n squared) and O(2 to the n). It usually describes the worst case. For example, binary search is O(log n), so a million elements need about 20 steps. Big Omega and Big Theta describe lower and tight bounds.
02

How does binary search work and what are common bugs?

Save to ▾
Show answer
Binary search works on sorted data by comparing the middle element with the target and discarding half the range each step, giving O(log n). Common bugs are computing mid as (low + high) / 2, which can overflow, so use low + (high - low) / 2; wrong loop conditions causing infinite loops; and off-by-one errors when finding first or last occurrences. Test with zero, one and two elements.
03

What is recursion and what are its risks?

Save to ▾
Show answer
Recursion is when a function calls itself on a smaller subproblem until reaching a base case. It expresses tree traversal, divide and conquer and backtracking naturally. Risks are stack overflow when depth is large, repeated work when subproblems overlap, like naive Fibonacci, and function call overhead. Use memoisation for overlapping subproblems and iterative versions when depth may be huge.
04

A recursive Fibonacci solution times out for n = 50. How do you fix it?

Save to ▾
Show answer
Naive recursion recomputes the same subproblems repeatedly, giving about O(1.6 to the n) calls. Memoise results in an array so each value is computed once, giving O(n), or iterate bottom-up keeping only the last two values for O(1) space. Use unsigned long long, since fib(50) exceeds the int range. Matrix exponentiation gives O(log n) for very large n.
05

A search on a sorted array of 10 lakh elements is done with a linear loop. How would you justify changing it?

Save to ▾
Show answer
Linear search takes up to 10 lakh comparisons, while binary search needs about 20, because log base 2 of 10 lakh is roughly 20. If searches are frequent, this is a huge saving at zero memory cost. If data changes often, keeping it sorted costs inserts, so consider a balanced tree or hash table. Measure with realistic workloads before and after.
06

Write binary search in C that returns the index of the target or -1.

Save to ▾
Show answer
Use an overflow safe midpoint. int binarySearch(const int *a, int n, int target) { int lo = 0, hi = n - 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (a[mid] == target) return mid; if (a[mid] < target) lo = mid + 1; else hi = mid - 1; } return -1; } Time O(log n). The array must be sorted in ascending order.
07

How do you keep improving your DSA skills while working full time?

Save to ▾
Show answer
Situation: after joining a services company I had little time for practice. Task: stay ready for product company interviews. Action: I set a goal of five problems a week on weekday mornings, joined weekend contests and kept a notebook of patterns and mistakes, revising it monthly. Result: within a year I reached a solid contest rating and cleared interviews for a backend role.
08

Compare quicksort, merge sort and heap sort.

Save to ▾
Show answer
Quicksort is O(n log n) on average and very fast in practice with in-place partitioning, but O(n squared) in the worst case with poor pivots and not stable. Merge sort is always O(n log n) and stable but needs O(n) extra memory. Heap sort is O(n log n) worst case and in place but not stable and slower due to poor cache use. C's qsort is usually a tuned hybrid.
09

What is dynamic programming?

Save to ▾
Show answer
Dynamic programming solves problems that have overlapping subproblems and optimal substructure by storing results of subproblems instead of recomputing them. Top-down memoisation caches recursive calls, while bottom-up tabulation fills a table iteratively. Classic examples are Fibonacci, 0/1 knapsack, longest common subsequence, coin change and edit distance. Defining the state and transition clearly is the hardest part.
10

What is the difference between greedy algorithms and dynamic programming?

Save to ▾
Show answer
A greedy algorithm makes the best local choice at each step and never revisits it, which works only when the greedy choice property holds, as in activity selection, Huffman coding and Dijkstra. Dynamic programming considers all relevant subproblem choices and combines them, so it works where greedy fails, such as 0/1 knapsack or coin change with arbitrary denominations. Greedy is faster when provably correct.
11

Your program sorts 1 crore integers in the range 0 to 999 and qsort is too slow. What would you do?

Save to ▾
Show answer
With a small known range, use counting sort: count occurrences in an array of 1000 counters, then rewrite the array in order. It runs in O(n + k) time with only 1000 extra integers, far faster than O(n log n) comparison sorts. For larger ranges, radix sort on bytes works well. qsort also pays a function call per comparison through its comparator pointer.
12

An interview asks for the minimum number of coins to make an amount. How do you approach it?

Save to ▾
Show answer
Greedy fails for some coin sets, such as coins 1, 3, 4 with amount 6, where greedy gives three coins but two coins of 3 is optimal. Use DP: dp[0] = 0 and dp[x] = 1 + min over coins c of dp[x - c], filling from 1 to the amount. Time is O(amount times coins) and space O(amount). Report -1 if the amount cannot be formed.
13

You must schedule the maximum number of non-overlapping meetings in one room. What algorithm do you use?

Save to ▾
Show answer
This is activity selection, solved greedily. Sort meetings by end time, then pick each meeting whose start is not earlier than the end of the last picked one. Choosing the earliest finishing meeting always leaves the most room for the rest, which can be proven by an exchange argument. Sorting dominates, giving O(n log n) time.
14

Implement quicksort in C using Lomuto partition.

Save to ▾
Show answer
Partition around the last element, then sort both sides. void swap(int *x, int *y) { int t = *x; *x = *y; *y = t; } int partition(int *a, int lo, int hi) { int pivot = a[hi], i = lo; for (int j = lo; j < hi; j++) if (a[j] < pivot) swap(&a[i++], &a[j]); swap(&a[i], &a[hi]); return i; } void quickSort(int *a, int lo, int hi) { if (lo < hi) { int p = partition(a, lo, hi); quickSort(a, lo, p - 1); quickSort(a, p + 1, hi); } }
15

Implement merge sort in C.

Save to ▾
Show answer
Split, sort halves, merge with a temp buffer. void merge(int *a, int l, int m, int r, int *tmp) { int i = l, j = m + 1, k = l; while (i <= m && j <= r) tmp[k++] = (a[i] <= a[j]) ? a[i++] : a[j++]; while (i <= m) tmp[k++] = a[i++]; while (j <= r) tmp[k++] = a[j++]; for (k = l; k <= r; k++) a[k] = tmp[k]; } void mergeSort(int *a, int l, int r, int *tmp) { if (l >= r) return; int m = l + (r - l) / 2; mergeSort(a, l, m, tmp); mergeSort(a, m + 1, r, tmp); merge(a, l, m, r, tmp); }
16

Tell me about a time you optimised an algorithm in a real project.

Save to ▾
Show answer
Situation: a C tool comparing two inventory files of 5 lakh rows took 25 minutes. Task: make it run in a nightly window of 2 minutes. Action: I found nested loops doing O(n squared) matching, sorted both files with qsort and merged them with two pointers, which is O(n log n). Result: runtime fell to 40 seconds, and the approach became our standard for file reconciliation jobs.
17

How do you handle a coding interview problem when you are stuck?

Save to ▾
Show answer
Situation: in an onsite round I could not see how to solve an interval problem. Task: still show strong problem solving. Action: I stated a brute force solution with its complexity, tried small examples aloud, noticed that sorting by start time helped and asked a clarifying question about overlaps. Result: I reached an O(n log n) solution with a small hint, and the feedback praised my communication.
18

What is backtracking? Give an example.

Save to ▾
Show answer
Backtracking builds a solution step by step and abandons a path as soon as it cannot lead to a valid answer, then tries the next option. It explores a search tree with pruning. Examples are N-Queens, Sudoku, generating permutations and subsets, and maze path finding. Time can be exponential, so good pruning and ordering choices matter a lot.
19

What is the master theorem used for?

Save to ▾
Show answer
The master theorem gives the time complexity of divide and conquer recurrences of the form T(n) = aT(n/b) + f(n). Compare f(n) with n to the power log base b of a. For merge sort, a = 2, b = 2 and f(n) = n, which match, giving O(n log n). For binary search, a = 1 and b = 2 with constant work, giving O(log n). It does not cover every recurrence.
20

What is amortised analysis? Give an example.

Save to ▾
Show answer
Amortised analysis averages the cost of operations over a sequence, so occasional expensive steps are spread over many cheap ones. A dynamic array that doubles when full copies all elements on resize, which is O(n), but because doubling happens rarely, n appends cost O(n) in total, so each append is O(1) amortised. Union-find with path compression is another classic example.
21

Quicksort in your code becomes very slow on already sorted input. Why and how do you fix it?

Save to ▾
Show answer
Picking the first or last element as pivot on sorted input makes every partition split into sizes n-1 and 0, so quicksort degrades to O(n squared) and recursion depth reaches n. Choose a random pivot or median of three, switch to insertion sort for small parts and recurse on the smaller side first to bound stack depth. Introsort switches to heap sort if recursion gets too deep.
22

A DP solution for a large grid uses too much memory. How can you reduce it?

Save to ▾
Show answer
Many grid DPs only need the previous row to compute the current one, so replace the 2D table with two 1D arrays or even one array updated in place, cutting memory from O(rows times cols) to O(cols). For knapsack, iterate capacity backwards in a single array. If you also need to reconstruct the path, store compact choice bits or use Hirschberg's divide and conquer technique.
23

How would you find the kth smallest element in an unsorted array efficiently?

Save to ▾
Show answer
Sorting takes O(n log n). A max heap of size k gives O(n log k), good when k is small or data streams in. Quickselect partitions like quicksort but recurses into one side only, giving O(n) average and O(n squared) worst case, which random pivots make unlikely. Median of medians guarantees O(n) worst case but is slower in practice.
24

Solve the 0/1 knapsack problem in C with a 1D DP array.

Save to ▾
Show answer
Iterate capacity backwards so each item is used once. int knapsack(const int *wt, const int *val, int n, int W) { int dp[W + 1]; for (int c = 0; c <= W; c++) dp[c] = 0; for (int i = 0; i < n; i++) { for (int c = W; c >= wt[i]; c--) { int take = dp[c - wt[i]] + val[i]; if (take > dp[c]) dp[c] = take; } } return dp[W]; } Time O(nW), space O(W).
25

Find the length of the longest common subsequence of two strings.

Save to ▾
Show answer
Classic 2D DP. int lcs(const char *a, const char *b) { int n = strlen(a), m = strlen(b); int dp[n + 1][m + 1]; for (int i = 0; i <= n; i++) { for (int j = 0; j <= m; j++) { if (i == 0 || j == 0) dp[i][j] = 0; else if (a[i - 1] == b[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = dp[i - 1][j] > dp[i][j - 1] ? dp[i - 1][j] : dp[i][j - 1]; } } return dp[n][m]; } For ABCBDAB and BDCABA it returns 4.

Frequently asked questions

How important is Sorting, Searching and Dynamic Programming in C Programming with DSA interviews?

Finish with core algorithm design. Learn Big O analysis, binary search and its variants, quicksort, merge sort, heap sort and counting sort, recursion and backtracking, greedy algorithms and dynamic programming problems such as knapsack, coin change and longest common subsequence, with tips to explain complexity clearly in interviews.

How should I use the Sorting, Searching and Dynamic Programming sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.