04. Solved Coding PYQs - Bitwise, Dynamic Programming & Matrix Problems
Module Focus: High-frequency Bitwise, DP, and Matrix Manipulation Problems
Target: 100% Test Case Pass Rate (Handling Integer Overflow, Negative Inputs, Edge Cases)
Problem 1: Find Two Non-Repeating Elements in Array (Bitwise XOR)
Problem Statement
Given an array where every element occurs twice except for two numbers which appear only once, find those two non-repeating numbers in $O(N)$ time complexity and $O(1)$ auxiliary space.
Solution Logic
- XOR all elements in array. All repeating numbers cancel out ($x \oplus x = 0$). Result $X = A \oplus B$ where $A, B$ are the two unique numbers.
- Find the rightmost set bit in $X$ using
mask = X & (-X). - Divide elements into two groups based on whether that bit is set or not.
- XORing each group independently yields $A$ and $B$.
Solution Implementations
C++ Solution
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
pair<int, int> findTwoUnique(const vector<int>& nums) {
int xorSum = 0;
for (int num : nums) {
xorSum ^= num;
}
// Get rightmost set bit mask
unsigned int rightmostBit = (unsigned int)xorSum & (-(unsigned int)xorSum);
int num1 = 0, num2 = 0;
for (int num : nums) {
if ((unsigned int)num & rightmostBit) {
num1 ^= num;
} else {
num2 ^= num;
}
}
if (num1 > num2) swap(num1, num2);
return {num1, num2};
}
int main() {
vector<int> nums = {2, 4, 7, 9, 2, 4};
pair<int, int> result = findTwoUnique(nums);
cout << "Two Unique Numbers: " << result.first << " and " << result.second << endl;
// Output: 7 and 9
return 0;
}
Java Solution
import java.util.Arrays;
public class TwoUniqueElements {
public static int[] findTwoUnique(int[] nums) {
int xorSum = 0;
for (int num : nums) {
xorSum ^= num;
}
// Rightmost set bit mask
int rightmostBit = xorSum & (-xorSum);
int num1 = 0, num2 = 0;
for (int num : nums) {
if ((num & rightmostBit) != 0) {
num1 ^= num;
} else {
num2 ^= num;
}
}
int[] res = new int[]{num1, num2};
Arrays.sort(res);
return res;
}
public static void main(String[] args) {
int[] nums = {2, 4, 7, 9, 2, 4};
int[] result = findTwoUnique(nums);
System.out.println("Two Unique Numbers: " + result[0] + " and " + result[1]);
// Output: 7 and 9
}
}
Python Solution
def find_two_unique(nums):
xor_sum = 0
for num in nums:
xor_sum ^= num
# Rightmost set bit mask
rightmost_bit = xor_sum & (-xor_sum)
num1, num2 = 0, 0
for num in nums:
if num & rightmost_bit:
num1 ^= num
else:
num2 ^= num
return sorted([num1, num2])
# Driver test
nums = [2, 4, 7, 9, 2, 4]
print("Two Unique Numbers:", find_two_unique(nums)) # Output: [7, 9]
Complexity Analysis
- Time Complexity: $\mathcal{O}(N)$ — Two passes over array of size $N$.
- Space Complexity: $\mathcal{O}(1)$ — In-place XOR bit manipulation.
Problem 2: Rotate Matrix 90 Degrees In-Place (Clockwise & Anti-Clockwise)
Problem Statement
Given an $N \times N$ 2D matrix representing an image, rotate the image by 90 degrees clockwise and 90 degrees anti-clockwise in-place without allocating another 2D matrix.
Solution Logic
1. Clockwise Rotation (90°)
- Transpose Matrix: Swap
matrix[i][j]withmatrix[j][i]for $i < j$. - Reverse Each Row: Reverse elements of every row horizontally.
2. Anti-Clockwise (Counter-Clockwise) Rotation (90°)
- Transpose Matrix: Swap
matrix[i][j]withmatrix[j][i]for $i < j$. - Reverse Each Column: Reverse elements of every column vertically (or reverse rows first, then transpose).
Solution Implementations
C++ Solution
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Rotate 90 degrees Clockwise
void rotateClockwise(vector<vector<int>>& matrix) {
int n = matrix.size();
// Step 1: Transpose matrix
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
swap(matrix[i][j], matrix[j][i]);
}
}
// Step 2: Reverse each row
for (int i = 0; i < n; i++) {
reverse(matrix[i].begin(), matrix[i].end());
}
}
// Rotate 90 degrees Anti-Clockwise
void rotateAntiClockwise(vector<vector<int>>& matrix) {
int n = matrix.size();
// Step 1: Transpose matrix
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
swap(matrix[i][j], matrix[j][i]);
}
}
// Step 2: Reverse each column
for (int j = 0; j < n; j++) {
for (int i = 0, k = n - 1; i < k; i++, k--) {
swap(matrix[i][j], matrix[k][j]);
}
}
}
int main() {
vector<vector<int>> matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
vector<vector<int>> matCW = matrix;
rotateClockwise(matCW);
cout << "90 Deg Clockwise Rotated Matrix:\n";
for (const auto& row : matCW) {
for (int val : row) cout << val << " ";
cout << "\n";
}
vector<vector<int>> matACW = matrix;
rotateAntiClockwise(matACW);
cout << "\n90 Deg Anti-Clockwise Rotated Matrix:\n";
for (const auto& row : matACW) {
for (int val : row) cout << val << " ";
cout << "\n";
}
return 0;
}
Java Solution
import java.util.Arrays;
public class MatrixRotator {
// 90 Degrees Clockwise
public static void rotateClockwise(int[][] matrix) {
int n = matrix.length;
// Step 1: Transpose
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// Step 2: Reverse each row
for (int i = 0; i < n; i++) {
int left = 0, right = n - 1;
while (left < right) {
int temp = matrix[i][left];
matrix[i][left] = matrix[i][right];
matrix[i][right] = temp;
left++;
right--;
}
}
}
// 90 Degrees Anti-Clockwise
public static void rotateAntiClockwise(int[][] matrix) {
int n = matrix.length;
// Step 1: Transpose
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// Step 2: Reverse each column
for (int j = 0; j < n; j++) {
int top = 0, bottom = n - 1;
while (top < bottom) {
int temp = matrix[top][j];
matrix[top][j] = matrix[bottom][j];
matrix[bottom][j] = temp;
top++;
bottom--;
}
}
}
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[][] cw = Arrays.stream(matrix).map(int[]::clone).toArray(int[][]::new);
rotateClockwise(cw);
System.out.println("90 Deg Clockwise Rotated Matrix:");
for (int[] row : cw) System.out.println(Arrays.toString(row));
int[][] acw = Arrays.stream(matrix).map(int[]::clone).toArray(int[][]::new);
rotateAntiClockwise(acw);
System.out.println("90 Deg Anti-Clockwise Rotated Matrix:");
for (int[] row : acw) System.out.println(Arrays.toString(row));
}
}
Python Solution
def rotate_clockwise(matrix):
n = len(matrix)
# Step 1: Transpose
for i in range(n):
for j in range(i + 1, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# Step 2: Reverse each row
for i in range(n):
matrix[i].reverse()
def rotate_anti_clockwise(matrix):
n = len(matrix)
# Step 1: Transpose
for i in range(n):
for j in range(i + 1, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# Step 2: Reverse each column
for j in range(n):
for i in range(n // 2):
matrix[i][j], matrix[n - 1 - i][j] = matrix[n - 1 - i][j], matrix[i][j]
# Driver test
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
cw = [row[:] for row in matrix]
rotate_clockwise(cw)
print("90 Deg Clockwise Rotated Matrix:", cw)
acw = [row[:] for row in matrix]
rotate_anti_clockwise(acw)
print("90 Deg Anti-Clockwise Rotated Matrix:", acw)
Complexity Analysis
- Time Complexity: $\mathcal{O}(N^2)$ — Visiting every cell twice (transpose + row/column reversal).
- Space Complexity: $\mathcal{O}(1)$ — In-place rotation.
Problem 3: 0/1 Knapsack Problem (Dynamic Programming)
Problem Statement
Given weights wt[] and values val[] of $N$ items, put these items in a knapsack of capacity $W$ to get the maximum total value in the knapsack. Each item can either be picked or not picked (0/1 choice).
Solution Implementations
C++ Solution
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int knapsack(int W, const vector<int>& wt, const vector<int>& val, int n) {
vector<int> dp(W + 1, 0);
for (int i = 0; i < n; i++) {
for (int w = W; w >= wt[i]; w--) {
dp[w] = max(dp[w], val[i] + dp[w - wt[i]]);
}
}
return dp[W];
}
int main() {
vector<int> val = {60, 100, 120};
vector<int> wt = {10, 20, 30};
int W = 50;
int n = val.size();
cout << "Maximum Value: " << knapsack(W, wt, val, n) << endl; // Output: 220
return 0;
}
Java Solution
public class Knapsack {
public static int knapsack(int W, int[] wt, int[] val, int n) {
int[] dp = new int[W + 1];
for (int i = 0; i < n; i++) {
for (int w = W; w >= wt[i]; w--) {
dp[w] = Math.max(dp[w], val[i] + dp[w - wt[i]]);
}
}
return dp[W];
}
public static void main(String[] args) {
int[] val = {60, 100, 120};
int[] wt = {10, 20, 30};
int W = 50;
int n = val.length;
System.out.println("Maximum Value: " + knapsack(W, wt, val, n)); // Output: 220
}
}
Python Solution
def knapsack(W, wt, val, n):
dp = [0] * (W + 1)
for i in range(n):
for w in range(W, wt[i] - 1, -1):
dp[w] = max(dp[w], val[i] + dp[w - wt[i]])
return dp[W]
# Driver test
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print("Maximum Value:", knapsack(W, wt, val, n)) # Output: 220
Complexity Analysis
- Time Complexity: $\mathcal{O}(N \times W)$ — Nested loop over $N$ items and $W$ capacity.
- Space Complexity: $\mathcal{O}(W)$ — Space-optimized 1D DP table.
Problem 4: Count Set Bits in an Integer (Popcount)
Problem Statement
Write an efficient function to count the number of set bits (1s) in a given positive integer $N$.
Solution Implementations
C++ Solution
#include <iostream>
using namespace std;
int countSetBits(int n) {
int count = 0;
while (n > 0) {
n &= (n - 1); // Clears the rightmost set bit (Brian Kernighan's Algorithm)
count++;
}
return count;
}
int main() {
int n = 29; // Binary: 11101
cout << "Set Bits Count: " << countSetBits(n) << endl; // Output: 4
return 0;
}
Java Solution
public class CountSetBits {
public static int countSetBits(int n) {
int count = 0;
while (n > 0) {
n &= (n - 1); // Clears the rightmost set bit
count++;
}
return count;
}
public static void main(String[] args) {
int n = 29; // Binary: 11101
System.out.println("Set Bits Count: " + countSetBits(n)); // Output: 4
}
}
Python Solution
def count_set_bits(n: int) -> int:
count = 0
while n > 0:
n &= (n - 1) # Clears the rightmost set bit
count += 1
return count
# Driver test
n = 29 # Binary: 11101
print("Set Bits Count:", count_set_bits(n)) # Output: 4
Complexity Analysis
- Time Complexity: $\mathcal{O}(K)$ — Where $K$ is the number of set bits in $N$ ($\le \log_2 N$).
- Space Complexity: $\mathcal{O}(1)$ — Uses zero auxiliary memory.
Problem 5: Array Transformation (Simulated Neighbor Modification)
Problem Statement
Given an array of integers arr, modify elements based on neighbor comparison:
- An element arr[i] is incremented by 1 if arr[i-1] > arr[i] and arr[i] < arr[i+1].
- An element arr[i] is decremented by 1 if arr[i-1] < arr[i] and arr[i] > arr[i+1].
- The first (arr[0]) and last (arr[n-1]) elements never change.
- Repeat transformations until no further elements change (array stabilizes). Return the stable array.
Solution Logic
- Create a copy of
arrat each iteration step to avoid using partially transformed values in the same step. - Iterate from index
1ton-2: - If
arr[i] < arr[i-1]andarr[i] < arr[i+1], setnext_arr[i] = arr[i] + 1. - Else if
arr[i] > arr[i-1]andarr[i] > arr[i+1], setnext_arr[i] = arr[i] - 1. - If
next_arrequalsarr, the array has stabilized $\implies$ break loop and returnarr.
Solution Implementations
C++ Solution
#include <iostream>
#include <vector>
using namespace std;
vector<int> transformArray(vector<int>& arr) {
int n = arr.size();
if (n <= 2) return arr;
bool changed = true;
while (changed) {
changed = false;
vector<int> nextArr = arr;
for (int i = 1; i < n - 1; i++) {
if (arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {
nextArr[i]++;
changed = true;
} else if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1]) {
nextArr[i]--;
changed = true;
}
}
arr = nextArr;
}
return arr;
}
int main() {
vector<int> arr = {6, 2, 3, 4, 1, 5};
vector<int> result = transformArray(arr);
cout << "Transformed Array: ";
for (int x : result) cout << x << " ";
cout << "\n";
// Output: 6 3 3 3 3 5
return 0;
}
Java Solution
import java.util.Arrays;
public class ArrayTransform {
public static int[] transformArray(int[] arr) {
int n = arr.length;
if (n <= 2) return arr;
boolean changed = true;
while (changed) {
changed = false;
int[] nextArr = arr.clone();
for (int i = 1; i < n - 1; i++) {
if (arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {
nextArr[i]++;
changed = true;
} else if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1]) {
nextArr[i]--;
changed = true;
}
}
arr = nextArr;
}
return arr;
}
public static void main(String[] args) {
int[] arr = {6, 2, 3, 4, 1, 5};
int[] result = transformArray(arr);
System.out.println("Transformed Array: " + Arrays.toString(result));
// Output: [6, 3, 3, 3, 3, 5]
}
}
Python Solution
def transform_array(arr: list[int]) -> list[int]:
n = len(arr)
if n <= 2:
return arr
changed = True
while changed:
changed = False
next_arr = list(arr)
for i in range(1, n - 1):
if arr[i] < arr[i - 1] and arr[i] < arr[i + 1]:
next_arr[i] += 1
changed = True
elif arr[i] > arr[i - 1] and arr[i] > arr[i + 1]:
next_arr[i] -= 1
changed = True
arr = next_arr
return arr
# Driver test
arr = [6, 2, 3, 4, 1, 5]
print("Transformed Array:", transform_array(arr)) # Output: [6, 3, 3, 3, 3, 5]
Complexity Analysis
- Time Complexity: $\mathcal{O}(D \times N)$ — Where $D$ is the number of transformation cycles until stabilization ($D \le \max(arr)$).
- Space Complexity: $\mathcal{O}(N)$ — Auxiliary copy array to avoid in-step state corruption.
Problem 6: Run-Length String Compression
Problem Statement
Implement a method to perform basic string compression using the counts of repeated characters (e.g., "aabcccccaaa" $\to$ "a2b1c5a3"). If the "compressed" string would not become smaller than the original string, your method should return the original string. You can assume the string has only uppercase and lowercase letters (a-z, A-Z).
Solution Logic
- Handle null or empty string edge cases immediately.
- Use a dynamic string buffer (
StringBuilderin Java,std::stringin C++, list join in Python). - Loop through characters, keeping track of consecutive frequency
count. - Append character and count whenever character changes or string end is reached.
- Compare length of compressed string vs original string and return the shorter one.
Solution Implementations
C++ Solution
#include <iostream>
#include <string>
using namespace std;
string compressString(const string& s) {
if (s.empty()) return s;
string compressed = "";
int count = 1;
for (size_t i = 0; i < s.length(); i++) {
if (i + 1 < s.length() && s[i] == s[i + 1]) {
count++;
} else {
compressed += s[i];
compressed += to_string(count);
count = 1;
}
}
return (compressed.length() < s.length()) ? compressed : s;
}
int main() {
string str1 = "aabcccccaaa";
string str2 = "abcd";
cout << str1 << " -> " << compressString(str1) << "\n"; // Output: a2b1c5a3
cout << str2 << " -> " << compressString(str2) << "\n"; // Output: abcd (original)
return 0;
}
Java Solution
public class StringCompressor {
public static String compressString(String s) {
if (s == null || s.isEmpty()) return s;
StringBuilder compressed = new StringBuilder();
int count = 1;
for (int i = 0; i < s.length(); i++) {
if (i + 1 < s.length() && s.charAt(i) == s.charAt(i + 1)) {
count++;
} else {
compressed.append(s.charAt(i));
compressed.append(count);
count = 1;
}
}
String result = compressed.toString();
return (result.length() < s.length()) ? result : s;
}
public static void main(String[] args) {
String str1 = "aabcccccaaa";
String str2 = "abcd";
System.out.println(str1 + " -> " + compressString(str1)); // Output: a2b1c5a3
System.out.println(str2 + " -> " + compressString(str2)); // Output: abcd
}
}
Python Solution
def compress_string(s: str) -> str:
if not s:
return s
compressed = []
count = 1
for i in range(len(s)):
if i + 1 < len(s) and s[i] == s[i + 1]:
count += 1
else:
compressed.append(s[i] + str(count))
count = 1
result = "".join(compressed)
return result if len(result) < len(s) else s
# Driver test
str1 = "aabcccccaaa"
str2 = "abcd"
print(f"{str1} -> {compress_string(str1)}") # Output: a2b1c5a3
print(f"{str2} -> {compress_string(str2)}") # Output: abcd
Complexity Analysis
- Time Complexity: $\mathcal{O}(N)$ — Single pass over string of length $N$.
- Space Complexity: $\mathcal{O}(N)$ — Space for storing compressed string output.