int binarySearch(vector<int> &nums, int target) {
int low =0, high = nums.size()-1;
while( low <= high ){
int mid = low + (high - low) / 2;
if( nums[mid] == target )
return mid;
else if( nums[mid] < target )
low = mid + 1;
else
high = mid -1;
}
return -1;
}
Tag: algorithms
Construct the Smallest Number
Developers flex on each with the strangest of ways. How green is your github commit history. Have you submitted a PR to a open source project. How well can you solve the silliest questions on leetcode / geeksforgeeks / hackerrank?
While normies use money and status as a measure of success. Coders have incelled their way into a paradise where the glow of the monitor is all you need.
Pray for death all you want, it’s not coming. Man up and start grinding.
You are given a 0-indexed string pattern
of length n
consisting of the characters 'I'
meaning increasing and 'D'
meaning decreasing.
A 0-indexed string num
of length n + 1
is created using the following conditions:
num
consists of the digits'1'
to'9'
, where each digit is used at most once.- If
pattern[i] == 'I'
, thennum[i] < num[i + 1]
. - If
pattern[i] == 'D'
, thennum[i] > num[i + 1]
.
Return the lexicographically smallest possible string num
that meets the conditions.
Example 1:
Input: pattern = "IIIDIDDD" Output: "123549876" Explanation: At indices 0, 1, 2, and 4 we must have that num[i] < num[i+1]. At indices 3, 5, 6, and 7 we must have that num[i] > num[i+1]. Some possible values of num are "245639871", "135749862", and "123849765". It can be proven that "123549876" is the smallest possible num that meets the conditions. Note that "123414321" is not possible because the digit '1' is used more than once.
Example 2:
Input: pattern = "DDD" Output: "4321" Explanation: Some possible values of num are "9876", "7321", and "8742". It can be proven that "4321" is the smallest possible num that meets the conditions.
Constraints:
1 <= pattern.length <= 8
pattern
consists of only the letters'I'
and'D'
.
class Solution {
public:
string smallestNumber(string pattern) {
string result;
stack<int> st;
for( int i = 0; i<= pattern.size(); i++ ){
st.push(i+1);
if ( i == pattern.length() || pattern[i] == 'I' )
while(!st.empty()){
result+=to_string( st.top() );
st.pop();
}
}
return result;
}
};
Generating Subsets using Backtracking
1863. Sum of All Subset XOR Totals
This is a good problem to grasp basics of backtracking
The XOR total of an array is defined as the bitwise XOR
of all its elements, or 0
if the array is empty.
- For example, the XOR total of the array
[2,5,6]
is2 XOR 5 XOR 6 = 1
.
Given an array nums
, return the sum of all XOR totals for every subset of nums
.
Note: Subsets with the same elements should be counted multiple times.
An array a
is a subset of an array b
if a
can be obtained from b
by deleting some (possibly zero) elements of b
.
Example 1:
Input: nums = [1,3] Output: 6 Explanation: The 4 subsets of [1,3] are: - The empty subset has an XOR total of 0. - [1] has an XOR total of 1. - [3] has an XOR total of 3. - [1,3] has an XOR total of 1 XOR 3 = 2. 0 + 1 + 3 + 2 = 6
Example 2:
Input: nums = [5,1,6] Output: 28 Explanation: The 8 subsets of [5,1,6] are: - The empty subset has an XOR total of 0. - [5] has an XOR total of 5. - [1] has an XOR total of 1. - [6] has an XOR total of 6. - [5,1] has an XOR total of 5 XOR 1 = 4. - [5,6] has an XOR total of 5 XOR 6 = 3. - [1,6] has an XOR total of 1 XOR 6 = 7. - [5,1,6] has an XOR total of 5 XOR 1 XOR 6 = 2. 0 + 5 + 1 + 6 + 4 + 3 + 7 + 2 = 28
Example 3:
Input: nums = [3,4,5,6,7,8] Output: 480 Explanation: The sum of all XOR totals for every subset is 480.
class Solution {
vector<vector<int>> subset;
void backtrack(vector<int> &nums,vector<int> ¤t,int index){
subset.push_back(current);
for(int i = index; i < nums.size(); i++ ){
current.push_back(nums[i]);
backtrack( nums, current, i+1);
current.pop_back();
}
}
public:
int subsetXORSum(vector<int>& nums) {
vector<int> current;
backtrack(nums,current,0);
int total_sum = 0;
for (const auto& sub : subset) {
int xor_sum = 0;
for (int num : sub) {
//std::cout<<num<<" ";
xor_sum ^= num;
}
//std::cout<<std::endl;
total_sum += xor_sum;
}
return total_sum;
}
};
k largest elements
Given an array arr[] of positive integers and an integer k, Your task is to return k largest elements in decreasing order.
Examples:
Input: arr[] = [12, 5, 787, 1, 23], k = 2 Output: [787, 23] Explanation: 1st largest element in the array is 787 and second largest is 23.
Input: arr[] = [1, 23, 12, 9, 30, 2, 50], k = 3 Output: [50, 30, 23] Explanation: Three Largest elements in the array are 50, 30 and 23.
Input: arr[] = [12, 23], k = 1 Output: [23] Explanation: 1st Largest element in the array is 23.
Constraints:
1 ≤ k ≤ arr.size() ≤ 106
1 ≤ arr[i] ≤ 106
class Solution {
std::vector<int> minHeapToVector(std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap) {
std::vector<int> result;
while (!minHeap.empty()) {
result.push_back(minHeap.top());
minHeap.pop();
}
std::reverse(result.begin(), result.end());
return result;
}
public:
vector<int> kLargest(vector<int>& arr, int k) {
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
for( int i : arr ){
if( minHeap.size() < k )
minHeap.push(i);
else if( minHeap.top()<=i ){
minHeap.pop();
minHeap.push(i);
}
}
return minHeapToVector(minHeap);
}
};
1079. Letter Tile Possibilities
You have n
tiles
, where each tile has one letter tiles[i]
printed on it.
Return the number of possible non-empty sequences of letters you can make using the letters printed on those tiles
.
Example 1:
Input: tiles = "AAB" Output: 8 Explanation: The possible sequences are "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA".
Example 2:
Input: tiles = "AAABBC" Output: 188
Example 3:
Input: tiles = "V"
Output: 1
Depth First Search Solution, which is more performant with time complexity of O(N!) and space complexity of O(N).
class Solution {
public:
int numTilePossibilities(string tiles) {
unordered_map<char, int> count;
for (char c : tiles) {
count[c]++;
}
return dfs(count);
}
private:
int dfs(unordered_map<char, int>& count) {
int sum = 0;
for (auto& [tile, cnt] : count) {
if (cnt == 0) continue;
sum++;
count[tile]--;
sum += dfs(count);
count[tile]++;
}
return sum;
}
};
Backtracking Solution:
class Solution {
private:
set<string> seq;
void backtrack(const string& tiles, string& current, vector<bool>& used){
if( !current.empty() )
seq.insert( current );
for( int i =0; i<tiles.length();i++){
if(used[i]) continue;
used[i]=true;
current.push_back(tiles[i]);
backtrack(tiles, current, used);
current.pop_back();
used[i]=false;
}
}
public:
int numTilePossibilities(string tiles) {
vector<bool> used(tiles.length(), false);
string current = "";
backtrack(tiles, current, used);
return seq.size();
}
};
Optimized Backtracking solution:
class Solution {
public:
void backtrack(unordered_map<char,int>&mapi,int &count){
for(auto&entry:mapi){
if(entry.second>0){
entry.second--;
count++;
backtrack(mapi,count);
entry.second++;
}
}
}
int numTilePossibilities(string tiles) {
unordered_map<char,int>mapi;
for(int i=0;i<tiles.size();i++){
mapi[tiles[i]]++;
}
int count=0;
backtrack(mapi,count);
return count;
}
};
Tuple with Same Product
Given an array nums
of distinct positive integers, return the number of tuples (a, b, c, d)
such that a * b = c * d
where a
, b
, c
, and d
are elements of nums
, and a != b != c != d
.
Example 1:
Input: nums = [2,3,4,6] Output: 8 Explanation: There are 8 valid tuples: (2,6,3,4) , (2,6,4,3) , (6,2,3,4) , (6,2,4,3) (3,4,2,6) , (4,3,2,6) , (3,4,6,2) , (4,3,6,2)
Example 2:
Input: nums = [1,2,4,5,10] Output: 16 Explanation: There are 16 valid tuples: (1,10,2,5) , (1,10,5,2) , (10,1,2,5) , (10,1,5,2) (2,5,1,10) , (2,5,10,1) , (5,2,1,10) , (5,2,10,1) (2,10,4,5) , (2,10,5,4) , (10,2,4,5) , (10,2,5,4) (4,5,2,10) , (4,5,10,2) , (5,4,2,10) , (5,4,10,2)
Constraints:
1 <= nums.length <= 1000
1 <= nums[i] <= 10<sup>4</sup>
- All elements in
nums
are distinct.
class Solution {
public:
int tupleSameProduct(vector<int>& nums) {
uint size = nums.size();
unordered_map<int, int> mp;
for( int i = 0; i < size; i++ )
for( int j = i +1; j< size; j++){
int prod = nums[i] * nums[j];
mp[prod]++;
}
int res = 0;
for( auto& [prod, cnt] : mp ){
int pairs = (cnt *(cnt-1)) / 2;
res += 8 * pairs;
}
return res;
}
};
1790. Check if One String Swap Can Make Strings Equal
You are given two strings s1
and s2
of equal length. A string swap is an operation where you choose two indices in a string (not necessarily different) and swap the characters at these indices.
Return true
if it is possible to make both strings equal by performing at most one string swap on exactly one of the strings. Otherwise, return false
.
Example 1:
Input: s1 = "bank", s2 = "kanb" Output: true Explanation: For example, swap the first character with the last character of s2 to make "bank".
Example 2:
Input: s1 = "attack", s2 = "defend" Output: false Explanation: It is impossible to make them equal with one string swap.
Example 3:
Input: s1 = "kelb", s2 = "kelb" Output: true Explanation: The two strings are already equal, so no string swap operation is required.
Constraints:
1 <= s1.length, s2.length <= 100
s1.length == s2.length
s1
ands2
consist of only lowercase English letters.
class Solution {
public:
bool areAlmostEqual(string s1, string s2) {
vector<int> index;
for( uint8_t i = 0; i < s1.length(); i++ ){
if( s1[i] != s2[i] )
index.push_back(i);
if( index.size() > 2)
return false;
}
if( index.size() == 2 ){
int i = index[0];
int j = index[1];
if( s1[i] == s2[j] && s1[j] == s2[i] ) return true;
}
return index.size() == 0;
}
};
Removing the Nth Node from a list.
https://leetcode.com/problems/remove-nth-node-from-end-of-list
Given the head
of a linked list, remove the n<sup>th</sup>
node from the end of the list and return its head.
Example 1:

Input: head = [1,2,3,4,5], n = 2 Output: [1,2,3,5]
Example 2:
Input: head = [1], n = 1 Output: []
Example 3:
Input: head = [1,2], n = 1 Output: [1]
Constraints:
- The number of nodes in the list is
sz
. 1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
Follow up: Could you do this in one pass?
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode* next) : val(x), next(next) {}
};
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode dummy(0, head);
ListNode* fast = &dummy;
ListNode* slow = &dummy;
// Move fast n+1 steps ahead
for (int i = 0; i <= n; i++) {
fast = fast->next;
}
// Move both pointers
while (fast) {
fast = fast->next;
slow = slow->next;
}
// Remove the nth node
slow->next = slow->next->next;
return dummy.next;
}
};
// Function to create a linked list from an array
ListNode* createLinkedList(int arr[], int size) {
if (size == 0) return nullptr;
ListNode* head = new ListNode(arr[0]);
ListNode* current = head;
for (int i = 1; i < size; i++) {
current->next = new ListNode(arr[i]);
current = current->next;
}
return head;
}
// Function to print a linked list
void printLinkedList(ListNode* head) {
while (head) {
cout << head->val << " -> ";
head = head->next;
}
cout << "NULL" << endl;
}
// Main function for testing
int main() {
int arr[] = {1, 2, 3, 4, 5};
int size = sizeof(arr) / sizeof(arr[0]);
int n = 2; // Remove the 2nd node from the end
// Create linked list
ListNode* head = createLinkedList(arr, size);
cout << "Original List: ";
printLinkedList(head);
// Call removeNthFromEnd function
Solution solution;
head = solution.removeNthFromEnd(head, n);
cout << "Updated List: ";
printLinkedList(head);
return 0;
}
2270. Number of Ways to Split Array
class Solution {
public:
int waysToSplitArray(vector<int>& nums) {
// Keep track of sum of elements on left and right sides
long long leftSum = 0, rightSum = 0;
// Initially all elements are on right side
for (int num : nums) {
rightSum += num;
}
int count = 0;
// Try each possible split position
for (int i = 0; i < nums.size() - 1; i++) {
// Move current element from right to left side
leftSum += nums[i];
rightSum -= nums[i];
// Check if this creates a valid split
if (leftSum >= rightSum) {
count++;
}
}
return count;
}
};
You are given a 0-indexed integer array nums
of length n
.
nums
contains a valid split at index i
if the following are true:
- The sum of the first
i + 1
elements is greater than or equal to the sum of the lastn - i - 1
elements. - There is at least one element to the right of
i
. That is,0 <= i < n - 1
.
Return the number of valid splits in nums
.
Example 1:
Input: nums = [10,4,-8,7] Output: 2 Explanation: There are three ways of splitting nums into two non-empty parts: - Split nums at index 0. Then, the first part is [10], and its sum is 10. The second part is [4,-8,7], and its sum is 3. Since 10 >= 3, i = 0 is a valid split. - Split nums at index 1. Then, the first part is [10,4], and its sum is 14. The second part is [-8,7], and its sum is -1. Since 14 >= -1, i = 1 is a valid split. - Split nums at index 2. Then, the first part is [10,4,-8], and its sum is 6. The second part is [7], and its sum is 7. Since 6 < 7, i = 2 is not a valid split. Thus, the number of valid splits in nums is 2.
Example 2:
Input: nums = [2,3,1,0] Output: 2 Explanation: There are two valid splits in nums: - Split nums at index 1. Then, the first part is [2,3], and its sum is 5. The second part is [1,0], and its sum is 1. Since 5 >= 1, i = 1 is a valid split. - Split nums at index 2. Then, the first part is [2,3,1], and its sum is 6. The second part is [0], and its sum is 0. Since 6 >= 0, i = 2 is a valid split.
Constraints:
2 <= nums.length <= 10<sup>5</sup>
-10<sup>5</sup> <= nums[i] <= 10<sup>5</sup>
1030. Matrix Cells in Distance Order
You are given four integers row
, cols
, rCenter
, and cCenter
. There is a rows x cols
matrix and you are on the cell with the coordinates (rCenter, cCenter)
.
Return the coordinates of all cells in the matrix, sorted by their distance from (rCenter, cCenter)
from the smallest distance to the largest distance. You may return the answer in any order that satisfies this condition.
The distance between two cells (r<sub>1</sub>, c<sub>1</sub>)
and (r<sub>2</sub>, c<sub>2</sub>)
is |r<sub>1</sub> - r<sub>2</sub>| + |c<sub>1</sub> - c<sub>2</sub>|
.
Example 1: Input: rows = 1, cols = 2, rCenter = 0, cCenter = 0 Output: [[0,0],[0,1]] Explanation: The distances from (0, 0) to other cells are: [0,1] Example 2: Input: rows = 2, cols = 2, rCenter = 0, cCenter = 1 Output: [[0,1],[0,0],[1,1],[1,0]] Explanation: The distances from (0, 1) to other cells are: [0,1,1,2] The answer [[0,1],[1,1],[0,0],[1,0]] would also be accepted as correct. Example 3: Input: rows = 2, cols = 3, rCenter = 1, cCenter = 2 Output: [[1,2],[0,2],[1,1],[0,1],[1,0],[0,0]] Explanation: The distances from (1, 2) to other cells are: [0,1,1,2,2,3] There are other answers that would also be accepted as correct, such as [[1,2],[1,1],[0,2],[1,0],[0,1],[0,0]].
class Solution {
public:
vector<vector<int>> allCellsDistOrder(int rows, int cols, int rCenter, int cCenter) {
queue<pair<int,int>> q;
vector<vector<int>> result;
vector<vector<bool>> visited( rows , vector<bool>(cols, false));
vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
q.push({rCenter, cCenter});
visited[rCenter][cCenter] = true;
while( !q.empty() ){
int size = q.size();
while(size > 0){
auto [currentRow, currentCol] = q.front();
result.push_back({currentRow, currentCol});
q.pop();
for (auto [dr, dc] : directions) {
int newRow = currentRow + dr;
int newCol = currentCol + dc;
if( newRow >= 0 && newRow < rows && newCol >=0 && newCol < cols
&& !visited[newRow][newCol]){
q.push({newRow,newCol});
visited[newRow][newCol] = true;
}
}
size--;
}
}
return result;
}
};