class Solution {
public:
bool isSubsetSum(vector<int>& arr, int sum) {
vector<vector<int>> memo(arr.size()+1, vector<int>(sum+1, -1));
function<bool(vector<int>&, int, int)> dp = [&](vector<int>& ar, int index, int sum){
if( sum == 0 ) return true;
if( index == 0 ) return false;
if( memo[index][sum] != -1 )
return memo[index][sum]==1;
bool result = dp(ar, index-1, sum );
if( ar[index-1] <= sum )
result = result || dp(ar, index-1, sum - ar[index-1]);
memo[index][sum] = result;
return result ;
};
return dp(arr, arr.size(), sum);
}
};
Category: geeksforgeeks
Parenthesis Checker
Given a string s, composed of different combinations of ‘(‘ , ‘)’, ‘{‘, ‘}’, ‘[‘, ‘]’, verify the validity of the arrangement.
An input string is valid if:
1. Open brackets must be closed by the same type of brackets.
2. Open brackets must be closed in the correct order.
Examples :
Input: s = "[{()}]" Output: true Explanation: All the brackets are well-formed.
Input: s = "[()()]{}" Output: true Explanation: All the brackets are well-formed.
Input: s = "([]"
Output: False
Explanation: The expression is not balanced as there is a missing ')' at the end.
Input: s = "([{]})"
Output: False
Explanation: The expression is not balanced as there is a closing ']' before the closing '}'.
Constraints:
1 ≤ s.size() ≤ 106
s[i] ∈ {‘{‘, ‘}’, ‘(‘, ‘)’, ‘[‘, ‘]’}
class Solution {
public:
bool isBalanced(string& s) {
stack<char> st;
unordered_map<char,char> mp = {
{'{','}'},
{'(',')'},
{'[',']'}
};
for( char c:s ) {
if( mp.count(c) )
st.push(c);
else {
if( st.empty() || mp[st.top()] != c )
return false;
st.pop();
}
}
return st.empty();
}
};
Stock Span
The stock span problem is a financial problem where we have a series of daily price quotes for a stock and we need to calculate the span of stock price for all days. The span arr[i] of the stocks price on a given day i is defined as the maximum number of consecutive days just before the given day, for which the price of the stock on the given day is less than or equal to its price on the current day.
Examples:
Input: arr[] = [100, 80, 60, 70, 60, 75, 85] Output: [1, 1, 1, 2, 1, 4, 6] Explanation: Traversing the given input span 100 is greater than equal to 100 and there are no more elements behind it so the span is 1, 80 is greater than equal to 80 and smaller than 100 so the span is 1, 60 is greater than equal to 60 and smaller than 80 so the span is 1, 70 is greater than equal to 60,70 and smaller than 80 so the span is 2 and so on. Hence the output will be 1 1 1 2 1 4 6.
Input: arr[] = [10, 4, 5, 90, 120, 80] Output: [1, 1, 2, 4, 5, 1] Explanation: Traversing the given input span 10 is greater than equal to 10 and there are no more elements behind it so the span is 1, 4 is greater than equal to 4 and smaller than 10 so the span is 1, 5 is greater than equal to 4,5 and smaller than 10 so the span is 2, and so on. Hence the output will be 1 1 2 4 5 1.
Input: arr[] = [11, 4, 5, 90, 120, 80] Output: [1, 1, 2, 4, 5, 1] Explanation: Traversing the given input span 11 is greater than equal to 11 and there are no more elements behind it so the span is 1, 4 is greater than equal to 4 and smaller than 10 so the span is 1, 5 is greater than equal to 4,5 and smaller than 10 so the span is 2, and so on. Hence the output will be 1 1 2 4 5 1.
Constraints:
1 ≤ arr.size()≤ 105
1 ≤ arr[i] ≤ 105
//{ Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
// } Driver Code Ends
class Solution {
public:
bool isBalanced(string& s) {
// code here
stack<char> st;
unordered_map<char,char> mp;
mp.set('{','}');
mp.set('(',')');
mp.set('[',']');
for( char c:s ){
if( mp[st.top()] == c )
st.pop();
} else
st.push(c);
}
return st.size() == 0;
}
};
//{ Driver Code Starts.
int main() {
int t;
string a;
cin >> t;
while (t--) {
cin >> a;
Solution obj;
if (obj.isBalanced(a))
cout << "true" << endl;
else
cout << "false" << endl;
cout << "~"
<< "\n";
}
}
// } Driver Code Ends
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);
}
};
in order traversal
this was the geeks for geeks problem of the day today
/* A Binary Tree node
class Node {
int data;
Node left, right;
Node(int item) {
data = item;
left = right = null;
}
}
*/
class Solution {
ArrayList<Integer> result = new ArrayList<>();
// Function to return a list containing the inorder traversal of the tree.
ArrayList<Integer> inOrder(Node root) {
// Code
inOrderHelper(root);
return result;
}
private void inOrderHelper( Node root ){
if( root == null ) return;
inOrderHelper( root.left );
result.add(root.data);
inOrderHelper( root.right );
}
}
Subarrays with sum K
Given an unsorted array of integers, find the number of continuous subarrays having sum exactly equal to a given number k.
Examples:
Input: arr = [10, 2, -2, -20, 10], k = -10 Output: 3 Explaination: Subarrays: arr[0...3], arr[1...4], arr[3...4] have sum exactly equal to -10.
Input: arr = [9, 4, 20, 3, 10, 5], k = 33 Output: 2 Explaination: Subarrays: arr[0...2], arr[2...4] have sum exactly equal to 33.
Input: arr = [1, 3, 5], k = 0
Output: 0 Explaination: No subarray with 0 sum.
Constraints:
- 1 ≤ arr.size() ≤ 105
- -103 ≤ arr[i] ≤ 103
- -107 ≤ k ≤ 107
class Solution {
public:
int countSubarrays(vector<int> &arr, int k) {
// unordered_map to store prefix sums frequencies
unordered_map<int, int> prefixSums;
int res = 0;
int currSum = 0;
for (int i = 0; i < arr.size(); i++) {
// Add current element to sum so far.
currSum += arr[i];
// If currSum is equal to desired sum, then a new
// subarray is found. So increase count of subarrays.
if (currSum == k)
res++;
// Check if the difference exists in the prefixSums map.
if (prefixSums.find(currSum - k) != prefixSums.end())
res += prefixSums[currSum - k];
// Add currSum to the set of prefix sums.
prefixSums[currSum]++;
}
return res;
}
};
Set Matrix Zeros
class Solution {
public:
void setMatrixZeroes(vector<vector<int>> &mat) {
int n = mat.size();
int m = mat[0].size();
bool firstRowHasZero = false;
bool firstColHasZero = false;
// Check if the first row has any zero
for (int j = 0; j < m; j++) {
if (mat[0][j] == 0) {
firstRowHasZero = true;
break;
}
}
// Check if the first column has any zero
for (int i = 0; i < n; i++) {
if (mat[i][0] == 0) {
firstColHasZero = true;
break;
}
}
// Use the first row and column to mark zeros
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (mat[i][j] == 0) {
mat[i][0] = 0;
mat[0][j] = 0;
}
}
}
// Update the matrix based on the markers
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (mat[i][0] == 0 || mat[0][j] == 0) {
mat[i][j] = 0;
}
}
}
// Update the first row if needed
if (firstRowHasZero) {
for (int j = 0; j < m; j++) {
mat[0][j] = 0;
}
}
// Update the first column if needed
if (firstColHasZero) {
for (int i = 0; i < n; i++) {
mat[i][0] = 0;
}
}
}
};
The idea here is using the first row and column as a Dynamic Programming table to mark which rows and columns need to be zeroed out.
That being done, then first column and row itself is updated at the end.
Search Sorted Matrix Solution in C++
The idea here is to implement binary search after discovering the correct row.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to search a given number in row-column sorted matrix.
bool searchMatrix(vector<vector<int>> &mat, int x) {
// code here
vector<int>*row = nullptr;
int rows = mat.size();
int cols = mat[0].size();
for( int i = 0; i < rows; i++ ){
if( mat[i][0] <= x && mat[i][cols-1] >= x ){
row = &(mat[i]);
break;
}
}
if( row == nullptr ) return false;
auto binarySearch = [row, x]( int low, int high ) -> bool{
while( low <= high ){
int mid = low + (high-low)/2;
if( (*row)[mid] == x ){
return true;
}else if((*row)[mid] < x ){
low = mid + 1;
} else {
high = mid - 1;
}
}
return false;
};
return binarySearch(0, cols -1 );
}
};
Min Chars to Add for Palindrome
Given a string s, the task is to find the minimum characters to be added at the front to make the string palindrome.
Note: A palindrome string is a sequence of characters that reads the same forward and backward.
Examples:
Input: s = "abc" Output: 2 Explanation: Add 'b' and 'c' at front of above string to make it palindrome : "cbabc"
Input: s = "aacecaaaa" Output: 2 Explanation: Add 2 a's at front of above string to make it palindrome : "aaaacecaaaa"
Constraints:
1 <= s.size() <= 106
Solution:
To determine the minimum characters to be added at the front of a string to make it a palindrome, we can solve the problem efficiently using a technique involving the longest prefix of the string that is also a suffix (LPS). This can be computed using the KMP algorithm. Below is the explanation, followed by the implementation.
Key Observation:
To make the string a palindrome by adding only characters to the front:
- We need to find the longest suffix of the string (starting at the end) that is already a palindrome.
- Once this suffix is identified, the remaining prefix of the string (which isn’t part of that palindromic suffix) will need to be reversed and added to the front of the string. The count of these characters is the output.
This amounts to finding:
- The longest prefix-suffix (LPS) of the string concatenated with its reverse (using a special separator character to avoid false matches).
Let’s break this into steps.
Steps to Find the Minimum Characters:
- Concatenate the String and Its Reverse:
- Create a new string:
temp = s + "$" + reverse(s)
(we use$
or any separator to distinguish the reversed part from the original string).
- Create a new string:
- Compute Longest Prefix Suffix (LPS):
- Use the KMP (Knuth-Morris-Pratt) algorithm on
temp
to compute the LPS array. - The LPS array gives us the length of the longest prefix of
temp
that is also a suffix. This indicates the maximum part ofs
(from the start) that matches the reverse part.
- Use the KMP (Knuth-Morris-Pratt) algorithm on
- Calculate Minimum Characters to Add:
- Subtract the longest prefix-suffix from the length of the original string:
Minimum characters to add = s.length() - LPS[length of temp - 1]
Implementation in C++:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// Function to compute the LPS array (used in KMP algorithm)
vector<int> computeLPS(const string& str) {
int n = str.length();
vector<int> lps(n, 0); // LPS array
int len = 0; // Length of previous longest prefix suffix
int i = 1;
// Compute LPS array
while (i < n) {
if (str[i] == str[len]) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) {
len = lps[len - 1]; // Backtrack
} else {
lps[i] = 0;
i++;
}
}
}
return lps;
}
// Function to find minimum characters to add at front to make the string palindrome
int minCharsToMakePalindrome(const string& s) {
string reversedStr = s;
reverse(reversedStr.begin(), reversedStr.end());
// Create the concatenated string
string temp = s + "$" + reversedStr;
// Compute LPS array for the concatenated string
vector<int> lps = computeLPS(temp);
// Length of the longest palindromic suffix
int longestPalindromicPrefix = lps.back();
// Minimum characters to add = length of s - longest palindromic prefix
return s.length() - longestPalindromicPrefix;
}
int main() {
string s;
cout << "Enter string: ";
cin >> s;
int result = minCharsToMakePalindrome(s);
cout << "Minimum characters to add: " << result << endl;
return 0;
}
Explanation of Code:
- Reverse the String:
- Create a reversed copy of
s
(reversedStr
).
- Create a reversed copy of
- Concatenate
s
,$
, andreversedStr
:- This ensures we identify the longest part of
s
that matches the reversed portion.
Ifs = “aacecaaa”
, thentemp = “aacecaaa$aaacecaa”
. - This ensures we identify the longest part of
- Compute LPS Array:
- Use the KMP algorithm to compute the longest prefix that is also a suffix for
temp
.
- Use the KMP algorithm to compute the longest prefix that is also a suffix for
- Find the Num of Characters to Add:
- Subtract the length of the longest palindromic prefix from the total length of
s
.
- Subtract the length of the longest palindromic prefix from the total length of
Find Minimum in Rotated Sorted Array
Suppose an array of length n
sorted in ascending order is rotated between 1
and n
times. For example, the array nums = [0,1,2,4,5,6,7]
might become:
[4,5,6,7,0,1,2]
if it was rotated4
times.[0,1,2,4,5,6,7]
if it was rotated7
times.
Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]]
1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]]
.
Given the sorted rotated array nums
of unique elements, return the minimum element of this array.
You must write an algorithm that runs in O(log n) time
.
Example 1:
Input: nums = [3,4,5,1,2] Output: 1 Explanation: The original array was [1,2,3,4,5] rotated 3 times.
Example 2:
Input: nums = [4,5,6,7,0,1,2] Output: 0 Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.
Example 3:
Input: nums = [11,13,15,17] Output: 11 Explanation: The original array was [11,13,15,17] and it was rotated 4 times.
Key Observations:
- A rotated sorted array is a sorted array that has been rotated at some pivot point. For example:
- Original array:
[1, 2, 3, 4, 5]
- Rotated arrays:
[4, 5, 1, 2, 3]
,[3, 4, 5, 1, 2]
- Original array:
- Minimum Element:
- The minimum element is the only element in the rotated array that is smaller than its predecessor.
- Alternatively, in the case of no rotation (e.g.,
[1, 2, 3, 4, 5]
), the first element is the smallest.
- Binary Search Approach:
- Since the array is sorted and rotated, we can use binary search to identify the minimum element in O(log n) time.
Steps to Solve:
- Binary Search:
- Set two pointers:
low = 0
(start of array) andhigh = n-1
(end of array). - While
low < high
, compute the middle index:mid = low + (high - low) / 2
. - Depending on the relationship between
arr[mid]
andarr[high]
:- If
arr[mid] > arr[high]
: The minimum must lie in the right half of the array (setlow = mid + 1
). - Otherwise, the minimum must be in the left half or at
mid
(sethigh = mid
).
- If
- When
low == high
, the minimum element is at indexlow
.
- Set two pointers:
- Return the Result:
- Output the element at
arr[low]
.
- Output the element at
Algorithm Complexity:
- Time Complexity:
Binary search operates in O(log n) time due to halving the search space in every iteration. - Space Complexity:
The algorithm uses O(1) space as we only manipulate indices and access the array directly.
Implementation in C++:
Here is the efficient implementation:
#include <iostream>
#include <vector>
using namespace std;
int findMinimum(const vector<int>& arr) {
int low = 0, high = arr.size() - 1;
// Binary search to find the minimum element
while (low < high) {
int mid = low + (high - low) / 2;
// If middle element is greater than the last element,
// the minimum must be in the right half
if (arr[mid] > arr[high]) {
low = mid + 1;
}
// Otherwise, the minimum is in the left half (or could be at mid)
else {
high = mid;
}
}
// At this point, low == high and points to the minimum element
return arr[low];
}
int main() {
vector<int> arr = {4, 5, 6, 7, 0, 1, 2}; // Example rotated array
cout << "The minimum element is: " << findMinimum(arr) << endl;
return 0;
}