Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 16

Easy :

1. Print a Binary Tree in Vertical Order | Set 2 (Hashmap based Method)


2. Find whether an array is subset of another array
3. Union and Intersection of two Linked Lists
4. Given an array A[] and a number x, check for pair in A[] with sum as x
5. Check if a given array contains duplicate elements within k distance from each other
6. Given an array of pairs, find all symmetric pairs in it
7. Group multiple occurrence of array elements ordered by first occurrence
8. How to check if two given sets are disjoint?
9. Pair with given product | Set 1 (Find if any pair exists)
10. Find missing elements of a range
11. Count pairs with given sum
12. Convert an array to reduced form | Set 1 (Simple and Hashing)
13. Return maximum occurring character in an input string
14. Find the first repeating element in an array of integers
15. Print All Distinct Elements of a given integer array
16. Find all permuted rows of a given row in a matrix
17. Find common elements in three linked lists
Intermediate :
1. Find Itinerary from a given list of tickets
2. Find number of Employees Under every Employee
3. Check if an array can be divided into pairs whose sum is divisible by k
4. Find four elements a, b, c and d in an array such that a+b = c+d
5. Find the largest subarray with 0 sum
6. Longest Consecutive Subsequence
7. Count distinct elements in every window of size k
8. Design a data structure that supports insert, delete, search and getRandom in constant time
9. Length of the largest subarray with contiguous elements
10. Find if there is a subarray with 0 sum
11. Print all subarrays with 0 sum
12. Find subarray with given sum | Set 2 (Handles Negative Numbers)
13. Vertical Sum in a given Binary Tree
14. Group Shifted String
15. Check for Palindrome after every character replacement Query
Hard :

1. Clone a Binary Tree with Random Pointers


2. Largest subarray with equal number of 0s and 1s
3. Palindrome Substring Queries
4. Find smallest range containing elements from k lists
5. Cuckoo Hashing – Worst case O(1) Lookup!
6. Subarrays with distinct elements
1) // loop to check if all elements
void getVerticalOrder(Node* root, int of arr2 also
hd, map<int, vector<int>> &m) // lies in arr1
{ for(int i = 0; i < n; i++)
// Base case {
if (root == NULL) if(!hset.contains(arr2[i]))
return; return false;
}
// Store current node in map 'm' return true;
m[hd].push_back(root->key); }

// Store nodes in left subtree


getVerticalOrder(root->left, hd-1, 3)
m);
LinkedList getIntersection(Node head1,
// Store nodes in right subtree Node head2)
getVerticalOrder(root->right, hd+1, {
m); HashSet<Integer> hset = new
} HashSet<>();
Node n1 = head1;
// The main function to print vertical Node n2 = head2;
oder of a binary tree LinkedList result = new
// with given root LinkedList();
void printVerticalOrder(Node* root)
{ // loop stores all the elements of
// Create a map and store vertical list1 in hset
oder in map using while(n1 != null)
// function getVerticalOrder() {
map < int,vector<int> > m; if(hset.contains(n1.data))
int hd = 0; {
getVerticalOrder(root, hd,m); hset.add(n1.data);
}
// Traverse the map and print nodes else
at every horigontal {
// distance (hd) hset.add(n1.data);
map< int,vector<int> > :: iterator }
it; n1 = n1.next;
for (it=m.begin(); it!=m.end(); }
it++)
{ //For every element of list2 present
for (int i=0; i<it- in hset
>second.size(); ++i) //loop inserts the element into the
cout << it->second[i] << " result
"; while(n2 != null)
cout << endl; {
} if(hset.contains(n2.data))
} {
result.push(n2.data);
}
2) n2 = n2.next;
}
static boolean isSubset(int arr1[], int return result;
arr2[], int m, }

int n) LinkedList getUnion(Node head1, Node


{ head2)
HashSet<Integer> hset= new {
HashSet<>(); // HashMap that will store the
// elements of the lists with their
// hset stores all the values of counts
arr1 HashMap<Integer, Integer> hmap = new
for(int i = 0; i < m; i++) HashMap<>();
{ Node n1 = head1;
if(!hset.contains(arr1[i])) Node n2 = head2;
hset.add(arr1[i]); LinkedList result = new
} LinkedList();
// loop inserts the elements and the
count of /* Driver program to test above function
// that element of list1 into the */
hmap int main()
while(n1 != null) {
{ int A[] = {1, 4, 45, 6, 10, 8};
if(hmap.containsKey(n1.data)) int n = 16;
{ int arr_size =
int val = hmap.get(n1.data); sizeof(A)/sizeof(A[0]);
hmap.put(n1.data, val + 1);
} printPairs(A, arr_size, n);
else
{ getchar();
hmap.put(n1.data, 1); return 0;
} }
n1 = n1.next;
} 5)

#include<bits/stdc++.h>
// loop further adds the elements of
using namespace std;
list2 with
// their counts into the hmap
while(n2 != null) /* C++ program to Check if a given array
{ contains duplicate
if(hmap.containsKey(n2.data)) elements within k distance from each
{ other */
int val = hmap.get(n2.data); bool checkDuplicatesWithinK(int arr[],
hmap.put(n2.data, val + 1); int n, int k)
} {
else // Creates an empty hashset
{ set<int> myset;
hmap.put(n2.data, 1);
} // Traverse the input array
n2 = n2.next; for (int i = 0; i < n; i++)
} {
// If already present n hash,
then we found
// Eventually add all the elements
// a duplicate within k distance
// into the result that are present
if (myset.find(arr[i]) !=
in the hmap
myset.end())
for(int a:hmap.keySet())
return true;
{
result.append(a);
} // Add this item to hashset
return result; myset.insert(arr[i]);
}
// Remove the k+1 distant item
if (i >= k)
4) myset.erase(arr[i-k]);
#include <stdio.h> }
#define MAX 100000 return false;
}
void printPairs(int arr[], int arr_size,
int sum) // Driver method to test above method
{ int main ()
int i, temp; {
bool binMap[MAX] = {0}; /*initialize int arr[] = {10, 5, 3, 4, 3, 5, 6};
hash map as 0*/ int n = sizeof(arr) /
sizeof(arr[0]);
for (i = 0; i < arr_size; i++) if (checkDuplicatesWithinK(arr, n,
{ 3))
temp = sum - arr[i]; cout << "Yes";
if (temp >= 0 && binMap[temp] == 1) else
printf("Pair with given sum %d cout << "No";
is (%d, %d) n", }
sum, arr[i], temp);
binMap[arr[i]] = 1; 6)
}
} void findSymPairs(int arr[][2], int row)
{ System.out.print(arr[
// Creates an empty hashMap hM i] + " ");
unordered_map<int, int> hM;
// And remove the
// Traverse through the given array element from HashMap.
for (int i = 0; i < row; i++) hM.remove(arr[i]);
{ }
// First and second elements of }
current pair }
int first = arr[i][0];
int sec = arr[i][1];
8)
// If found and value in hash
matches with first bool areDisjoint(int set1[], int set2[],
// element of this pair, we int n1, int n2)
found symmetry {
if (hM.find(sec) != hM.end() && // Creates an empty hashset
hM[sec] == first) set<int> myset;
cout << "(" << sec << ", "
<< first << ")" <<endl; // Traverse the first set and store
its elements in hash
for (int i = 0; i < n1; i++)
else // Else put sec element of
myset.insert(set1[i]);
this pair in hash
hM[first] = sec;
// Traverse the second set and check
}
if any element of it
}
// is already in hash or not.
for (int i = 0; i < n2; i++)
7) if (myset.find(set2[i]) !=
myset.end())
static void orderedGroup(int arr[]) return false;
{
// Creates an empty hashmap return true;
HashMap<Integer, Integer> hM = }
new HashMap<Integer, Integer>();

// Traverse the array elements, 9)


and store count for every element
bool isProduct(int arr[], int n, int x)
// in HashMap
{
for (int i=0; i<arr.length; i++)
// Consider all possible pairs and
{
check for
// Check if element is
// every pair.
already in HashMap
for (int i=0; i<n-1; i++)
Integer prevCount =
for (int j=i+1; i<n; i++)
hM.get(arr[i]);
if (arr[i] * arr[j] == x)
if (prevCount == null)
return true;
prevCount = 0;
return false;
// Increment count of element
}
element in HashMap
hM.put(arr[i], prevCount +
1); 10)
}
void printMissing(int arr[], int n, int
// Traverse array again low,
for (int i=0; i<arr.length; i++) int
{ high)
// Check if this is first {
occurrence // Insert all elements of arr[] in
Integer count set
= hM.get(arr[i]); unordered_set<int> s;
if (count != null) for (int i=0; i<n; i++)
{ s.insert(arr[i]);
// If yes, then print
the element 'count' times // Traverse throught the range an
for (int j=0; j<count; print all
j++) // missing elements
for (int x=low; x<=high; x++) // Convert array by taking positions
if (s.find(x) == s.end()) from
cout << x << " "; // umap
} for (int i = 0; i < n; i++)
11) arr[i] = umap[arr[i]];
}
int getPairsCount(int arr[], int n, int
sum)
{ 13)
unordered_map<int, int> m;
char getMaxOccuringChar(char* str)
// Store counts of all elements in {
map m // Create array to keep the count of
for (int i=0; i<n; i++) individual
m[arr[i]]++; // characters and initialize the
array as 0
int twice_count = 0; int count[ASCII_SIZE] = {0};

// iterate through each element and // Construct character count array


increment the from the input
// count (Notice that every pair is // string.
counted twice) int len = strlen(str);
for (int i=0; i<n; i++) for (int i=0; i<len; i++)
{ count[str[i]]++;
twice_count += m[sum-arr[i]];
int max = -1; // Initialize max
// if (arr[i], arr[i]) pair count
satisfies the condition, char result; // Initialize result
// then we need to ensure that
the count is // Traversing through the string and
// decreased by one such that maintaining
the (arr[i], arr[i]) // the count of each character
// pair is not considered for (int i = 0; i < len; i++) {
if (sum-arr[i] == arr[i]) if (max < count[str[i]]) {
twice_count--; max = count[str[i]];
} result = str[i];
}
// return the half of twice_count }
return twice_count/2;
} return result;
}

12)
14)
void convert(int arr[], int n)
{ void printFirstRepeating(int arr[], int
// Create a temp array and copy n)
contents {
// of arr[] to temp // Initialize index of first
int temp[n]; repeating element
memcpy(temp, arr, n*sizeof(int)); int min = -1;

// Sort temp array // Creates an empty hashset


sort(temp, temp + n); set<int> myset;

// Create a hash table. Refer // Traverse the input array from


// http://tinyurl.com/zp5wgef right to left
unordered_map<int, int> umap; for (int i = n - 1; i >= 0; i--)
{
// One by one insert elements of // If element is already in hash
sorted set, update min
// temp[] and assign them values if (myset.find(arr[i]) !=
from 0 myset.end())
// to n-1 min = i;
int val = 0;
for (int i = 0; i < n; i++) else // Else add element to
umap[temp[i]] = val++; hash set
myset.insert(arr[i]);
} cout << i << ", ";
}
// Print the result }
if (min != -1)
cout << "The first repeating
element is " << arr[min]; 17)
else
struct Node {
cout << "There are no repeating
int data;
elements";
struct Node* next;
}
};

15) /* A utility function to insert a node


at the
static void printDistinct(int arr[]) beginning of a linked list */
{ void push(struct Node** head_ref, int
// Creates an empty hashset new_data)
HashSet<Integer> set = new {
HashSet<>(); struct Node* new_node =
(struct Node
// Traverse the input array *)malloc(sizeof(struct Node));
for (int i=0; i<arr.length; i++) new_node->data = new_data;
{ new_node->next = (*head_ref);
// If not present, then put (*head_ref) = new_node;
it in hashtable and print it }
if (!set.contains(arr[i]))
{ /* print the common element in between
set.add(arr[i]); given three linked list*/
System.out.print(arr[i] void Common(struct Node* head1,
+ " "); struct Node* head2, struct
} Node* head3)
} {
}
// Creating empty hash table;
unordered_map<int, int> hash;
16)

void permutatedRows(int mat[][MAX], int struct Node* p = head1;


m, int n, int r) while (p != NULL) {
{
// Creating an empty set // set frequency by 1
unordered_set<int> s; hash[p->data] = 1;
p = p->next;
// Count frequencies of elements in }
given row r
for (int j=0; j<n; j++) struct Node* q = head2;
s.insert(mat[r][j]); while (q != NULL) {

// Traverse through all remaining // if the element is already


rows exist in the
for (int i=0; i<m; i++) // linked list set its frequency
{ 2
// we do not need to check for if (hash.find(q->data) !=
given row r hash.end())
if (i==r) hash[q->data] = 2;
continue; q = q->next;
}
// initialize hash i.e; count
frequencies struct Node* r = head3;
// of elements in row i while (r != NULL) {
int j; if (hash.find(r->data) !=
for (j=0; j<n; j++) hash.end() &&
if (s.find(mat[i][j]) == hash[r->data] == 2)
s.end())
break; // if the element frquancy is 2
if (j != n) it means
continue; // its present in both the first
and second
// linked list set its frquancy System.out.print(start + "-
3 >" + to + ", ");
hash[r->data] = 3; start = to;
r = r->next; to = dataSet.get(to);
} }
}
}
for (auto x : hash) {

// if current frequency is 3 its 2)


means
// element is common in all the private static void
given populateResult(Map<String, String>
// linked list dataSet)
if (x.second == 3) {
cout << x.first << " "; // To store reverse of original
} map, each key will have 0
} // to multiple values
Map<String, List<String>>
mngrEmpMap =
1) private static void new
printResult(Map<String, String> dataSet) HashMap<String, List<String>>();

{ // To fill mngrEmpMap, iterate


// To store reverse of given map through the given map
Map<String, String> reverseMap = for (Map.Entry<String,String>
new HashMap<String, String>(); entry: dataSet.entrySet())
{
// To fill reverse map, iterate String emp = entry.getKey();
through the given map String mngr =
for (Map.Entry<String,String> entry.getValue();
entry: dataSet.entrySet()) if (!emp.equals(mngr)) //
reverseMap.put(entry.getValu excluding emp-emp entry
e(), entry.getKey()); {
// Get the previous list
// Find the starting point of of direct reports under
itinerary // current 'mgr' and add
String start = null; the current 'emp' to the list
for (Map.Entry<String,String> List<String>
entry: dataSet.entrySet()) directReportList = mngrEmpMap.get(mngr);
{
if // If 'emp' is the first
(!reverseMap.containsKey(entry.getKey()) employee under 'mgr'
) if (directReportList ==
{ null)
start = directReportList =
entry.getKey(); new ArrayList<String>();
break;
} directReportList.add(emp
} );

// If we could not find a // Replace old value for


starting point, then something wrong 'mgr' with new
// with input // directReportList
if (start == null) mngrEmpMap.put(mngr,
{ directReportList);
System.out.println("Invalid }
Input"); }
return;
} // Now use manager-Emp map built
above to populate result
// Once we have starting point, // with use of
we simple need to go next, next populateResultUtil()
// of next using given hash map
String to = dataSet.get(start); // note- we are iterating over
while (to != null) original emp-manager map and
{
// will use mngr-emp map in }
helper to get the count
for (String mngr:
dataSet.keySet()) 4)
populateResultUtil(mngr,
mngrEmpMap); bool findPairs(int arr[], int n)
} {
3) // Create an empty Hash to store
mapping from sum to
bool canPairs(int arr[], int n, int k) // pair indexes
{ map<int, pair<int, int> > Hash;
// An odd length array cannot be
divided into pairs // Traverse through all possible
if (n & 1) pairs of arr[]
return false; for (int i = 0; i < n; ++i)
{
// Create a frequency array to count for (int j = i + 1; j < n; ++j)
occurrences {
// of all remainders when divided by // If sum of current pair is
k. not in hash,
map<int, int> freq; // then store it and
continue to next pair
// Count occurrences of all int sum = arr[i] + arr[j];
remainders if (Hash.find(sum) ==
for (int i = 0; i < n; i++) Hash.end())
freq[arr[i] % k]++; Hash[sum] = make_pair(i,
j);
// Traverse input array and use
freq[] to decide else // Else (Sum already
// if given array can be divided in present in hash)
pairs {
for (int i = 0; i < n; i++) // Find previous pair
{ pair<int, int> pp =
// Remainder of current element Hash[sum];// pp->previous pair
int rem = arr[i] % k;
// Since array elements
// If remainder with current are distinct, we don't
element divides // need to check if any
// k into two halves. element is common among pairs
if (2*rem == k) cout << "(" <<
{ arr[pp.first] << ", " << arr[pp.second]
// Then there must be even << ") and (" <<
occurrences of arr[i] << ", " << arr[j] << ")n";
// such remainder return true;
if (freq[rem] % 2 != 0) }
return false; }
} }

// If remainder is 0, then there cout << "No pairs found";


must be two return false;
// elements with 0 remainder }
else if (rem == 0) 5)
{
if (freq[rem] & 1) int maxLen(int arr[], int n)
return false; {
} // Map to store the previous sums
unordered_map<int, int> presum;
// Else number of occurrences of
remainder int sum = 0; // Initialize
// must be equal to number of the sum of elements
occurrences of int max_len = 0; // Initialize
// k - remainder result
else if (freq[rem] != freq[k -
rem]) // Traverse through the given array
return false; for(int i=0; i<n; i++)
} {
return true; // Add current element to sum
sum += arr[i]; 7)
if (arr[i]==0 && max_len==0) void countDistinct(int arr[], int k, int
max_len = 1; n)
if (sum == 0) {
max_len = i+1; // Creates an empty hashmap hm
map<int, int> hm;
// Look for this sum in Hash
table // initialize distinct element count
if(presum.find(sum) != for current window
presum.end()) int dist_count = 0;
{
// If this sum is seen // Traverse the first window and
before, then update max_len store count
max_len = max(max_len, i- // of every element in hash map
presum[sum]); for (int i = 0; i < k; i++)
} {
else if (hm[arr[i]] == 0)
{ {
// Else insert this sum with dist_count++;
index in hash table }
presum[sum] = i; hm[arr[i]] += 1;
} }
}
// Print count of first window
return max_len; cout << dist_count << endl;
}
// Traverse through the remaining
array
6) for (int i = k; i < n; i++)
{
int findLongestConseqSubseq(int arr[], // Remove first element of previous
int n) window
{ // If there was only one
unordered_set<int> S; occurrence, then reduce distinct count.
int ans = 0; if (hm[arr[i-k]] == 1)
{
// Hash all the array elements dist_count--;
for (int i = 0; i < n; i++) }
S.insert(arr[i]); // reduce count of the removed
element
// check each possible sequence from hm[arr[i-k]] -= 1;
the start
// then update optimal length // Add new element of current window
for (int i=0; i<n; i++) // If this element appears first
{ time,
// if current element is the // increment distinct element count
starting
// element of a sequence if (hm[arr[i]] == 0)
if (S.find(arr[i]-1) == S.end()) {
{ dist_count++;
// Then check for next }
elements in the hm[arr[i]] += 1;
// sequence
int j = arr[i]; // Print count of current window
while (S.find(j) != S.end()) cout << dist_count << endl;
j++; }
}
// update optimal length if
this length
// is more 8)
ans = max(ans, j - arr[i]);
} void add(int x)
} {
return ans; // If ekement is already
} present, then noting to do
if(Map.find(x) != Map.end())
return; // One by one fix the starting
points
// Else put element at the end for (int i=0; i<n-1; i++)
of arr[] {
int index = arr.size(); // Create an empty hash set and
arr.push_back(x); // add i'th element to it.
set<int> myset;
// and hashmap also myset.insert(arr[i]);
Map.insert(std::pair<int,int>(x,
index)); // Initialize max and min in
} // current subarray
int mn = arr[i], mx = arr[i];
// function to remove a number to DS
in O(1) // One by one fix ending points
void remove(int x) for (int j=i+1; j<n; j++)
{ {
// element not found then return // If current element is
if(Map.find(x) == Map.end()) already
return; // in hash set, then this
subarray
// remove element from map // cannot contain contiguous
int index = Map.at(x); elements
Map.erase(x); if (myset.find(arr[j]) !=
myset.end())
// swap with last element in arr break;
// then remove element at back
int last = arr.size() - 1; // Else add current element
swap(arr[index], arr[last]); to hash
arr.pop_back(); // set and update min, max
if required.
// Update hash table for new myset.insert(arr[j]);
index of last element mn = min(mn, arr[j]);
Map.at(arr[index]) = index; mx = max(mx, arr[j]);
}
// We have already checked
// Returns index of element if for
element is present, otherwise null // duplicates, now check for
int search(int x) other
{ // property and update
if(Map.find(x) != Map.end()) max_len
return Map.at(x); // if needed
return -1; if (mx - mn == j - i)
} max_len = max(max_len,
mx - mn + 1);
}
// Returns a random element from
}
myStructure
return max_len; // Return result
int getRandom()
}
{
// Find a random index from 0 to
size - 1
srand (time(NULL)); 10)
int random_index = rand() %
bool subArrayExists(int arr[], int n)
arr.size();
{
unordered_map<int,bool> sumMap;
// Return element at randomly
picked index
// Traverse throught array and store
return arr.at(random_index);
prefix sums
}
int sum = 0;
}
for (int i = 0 ; i < n ; i++)
{
sum += arr[i];
9)
// If prefix sum is 0 or it is
int findLength(int arr[], int n)
already present
{
if (sum == 0 || sumMap[sum] ==
int max_len = 1; // Inialize result
true)
return true; void subArraySum(int arr[], int n, int
sum)
sumMap[sum] = true; {
} // create an empty map
return false; unordered_map<int, int> map;
}
// Maintains sum of elements so far
int curr_sum = 0;
11)
for (int i = 0; i < n; i++)
vector< pair<int, int> > {
findSubArrays(int arr[], int n) // add current element to
{ curr_sum
// create an empty map curr_sum = curr_sum + arr[i];
unordered_map<int, vector<int> >
map; // if curr_sum is equal to
target sum
// create an empty vector of pairs // we found a subarray starting
to store from index 0
// subarray starting and ending // and ending at index i
index if (curr_sum == sum)
vector <pair<int, int>> out; {
cout << "Sum found between
// Maintains sum of elements so far indexes "
int sum = 0; << 0 << " to " << i <<
endl;
for (int i = 0; i < n; i++) return;
{ }
// add current element to sum
sum += arr[i]; // If curr_sum - sum already
exists in map
// if sum is 0, we found a // we have found a subarray with
subarray starting target sum
// from index 0 and ending at if (map.find(curr_sum - sum) !=
index i map.end())
if (sum == 0) {
out.push_back(make_pair(0, cout << "Sum found between
i)); indexes "
<< map[curr_sum - sum]
// If sum already exists in the + 1
map there exists << " to " << i << endl;
// at-least one subarray ending return;
at index i with }
// 0 sum
if (map.find(sum) != map.end()) map[curr_sum] = i;
{ }
// map[sum] stores starting
index of all subarrays // If we reach here, then no
vector<int> vc = map[sum]; subarray exists
for (auto it = vc.begin(); cout << "No subarray with given sum
it != vc.end(); it++) exists";
out.push_back(make_pair( }
*it + 1, i));
}
13)
// Important - no else
map[sum].push_back(i); struct Node
} {
int data;
// return output vector struct Node *left, *right;
return out; };
}
// A utility function to create a new
// Binary Tree node
Node* newNode(int data)
12)
{
Node *temp = new Node;
temp->data = data;
temp->left = temp->right = NULL; // This string will be 1 less length
return temp; than str
} return shift;
}
// Traverses the tree in Inoorder form
and // Method for grouping shifted string
// populates a hashMap that contains the void groupShiftedString(string str[],
// vertical sum int n)
void verticalSumUtil(Node *node, int hd, {
map<int, int> &Map) // map for storing indices of string
{ which are
// Base case // in same group
if (node == NULL) return; map< string, vector<int> > groupMap;
for (int i = 0; i < n; i++)
// Recur for left subtree {
verticalSumUtil(node->left, hd-1, string diffStr =
Map); getDiffString(str[i]);
groupMap[diffStr].push_back(i);
// Add val of current node to }
// map entry of corresponding hd
Map[hd] += node->data; // iterating through map to print
group
// Recur for right subtree for (auto it=groupMap.begin();
verticalSumUtil(node->right, hd+1, it!=groupMap.end();
Map);
} it++)
{
// Function to find vertical sum vector<int> v = it->second;
void verticalSum(Node *root) for (int i = 0; i < v.size();
{ i++)
// a map to store sum of each cout << str[v[i]] << " ";
horizontal cout << endl;
// distance }
map < int, int> Map; }
map < int, int> :: iterator it;

// populate the map 15)


verticalSumUtil(root, 0, Map);
void Query(string &str, int Q)
// Prints the values stored by {
VerticalSumUtil() int n = str.length();
for (it = Map.begin(); it !=
Map.end(); ++it) // create an empty set that store
{ indexes of
cout << it->first << ": " // unequal location in palindrome
<< it->second << endl; unordered_set<int> S;
}
} // we store indexes that are unequal
in palindrome
// traverse only first half of
14) string
for (int i=0; i<n/2; i++)
string getDiffString(string str) if (str[i] != str[n-1-i])
{ S.insert(i);
string shift = "";
for (int i = 1; i < str.length(); // traversal the query
i++) for (int q=1; q<=Q; q++)
{ {
int dif = str[i] - str[i-1]; // query 1: i1 = 3, i2 = 0, ch =
if (dif < 0) 'e'
dif += ALPHA; // query 2: i1 = 0, i2 = 2, ch =
's'
// Representing the difference int i1, i2;
as char char ch;
shift += (dif + 'a'); cin >> i1 >> i2 >> ch;
}
// Replace characters at indexes // copyLeftRightNode() and copyRandom()
i1 & i2 with Node* cloneTree(Node* tree)
// new char 'ch' {
str[i1] = str [i2] = ch; if (tree == NULL)
return NULL;
// If i1 and/or i2 greater than map<Node *, Node *> *mymap =
n/2 new map<Node *, Node *>;
// then convert into first half Node* newTree =
index copyLeftRightNode(tree, mymap);
if (i1 > n/2) copyRandom(tree, newTree, mymap);
i1 = n- 1 -i1; return newTree;
if (i2 > n/2) }
i2 = n -1 - i2;

// call addRemoveUnequal 2)
function to insert and remove
// unequal indexes int findSubArray(int arr[], int n)
addRemoveUnequal(str, i1 , n, S {
); // variables to store result values
addRemoveUnequal(str, i2 , n, S
); int maxsize = -1, startindex;

// if set is not empty then // Create an auxiliary array


string is not palindrome sunmleft[].
S.empty()? cout << "YES\n" : // sumleft[i] will be sum of array
cout << "NO\n"; // elements from arr[0] to arr[i]
}
} int sumleft[n];

// For min and max values in


1) sumleft[]

Node* copyLeftRightNode(Node* treeNode, int min, max;


map<Node *, Node *> *mymap) int i;
{
if (treeNode == NULL) // Fill sumleft array and get min
return NULL; and max
Node* cloneNode = newNode(treeNode- // values in it. Consider 0 values
>key); in arr[]
(*mymap)[treeNode] = cloneNode; // as -1
cloneNode->left =
copyLeftRightNode(treeNode->left, sumleft[0] = ((arr[0] == 0)? -1: 1);
mymap); min = arr[0]; max = arr[0];
cloneNode->right = for (i=1; i<n; i++)
copyLeftRightNode(treeNode->right, {
mymap); sumleft[i] = sumleft[i-1] +
return cloneNode; ((arr[i] == 0)?
} -1: 1);
if (sumleft[i] < min)
// This function copies random node by min = sumleft[i];
using the hashmap built by if (sumleft[i] > max)
// copyLeftRightNode() max = sumleft[i];
void copyRandom(Node* treeNode, Node* }
cloneNode, map<Node *, Node *> *mymap)
{ // Now calculate the max value of j
if (cloneNode == NULL) - i such
return; // that sumleft[i] = sumleft[j]. The
cloneNode->random idea is
= (*mymap)[treeNode->random]; // to create a hash table to store
copyRandom(treeNode->left, indexes of all
cloneNode->left, mymap); // visited values.
copyRandom(treeNode->right, // If you see a value again, that it
cloneNode->right, mymap); is a case of
} // sumleft[i] = sumleft[j]. Check if
this j-i is
// This function makes the clone of // more than maxsize.
given tree. It mainly uses
// The optimum size of hash will be {
max-min+1 as for (int i=0; i<=m-1; i++)
// these many different values of {
sumleft[i] are int L = q[i].L;
// possible. Since we use optimum int R = q[i].R;
size, we need
// to shift all values in sumleft[] // Hash Value of Substring [L,R]
by min before unsigned long long hash_LR =
// using them as an index in hash[]. ((prefix[R+1]-
prefix[L]+MOD)%MOD *
int hash[max-min+1]; findMMI(power[L])%MOD)%MOD;

// Initialize hash table // Reverse Hash Value of


Substring [L,R]
for (i=0; i<max-min+1; i++) unsigned long long
hash[i] = -1; reverse_hash_LR =
((suffix[n-L]-suffix[n-R-
for (i=0; i<n; i++) 1]+MOD)%MOD *
{ findMMI(power[n-R-
// Case 1: when the subarray 1])%MOD)%MOD;
starts from
// index 0 // If both are equal then the
substring is a palindrome
if (sumleft[i] == 0) if (hash_LR == reverse_hash_LR )
{ {
maxsize = i+1; if (isPalindrome(str, L, R)
startindex = 0; == true)
} printf("The Substring
[%d %d] is a "
// Case 2: fill hash table "palindrome\n",
value. If already L, R);
// filled, then use it else
printf("The Substring
if (hash[sumleft[i]-min] == -1) [%d %d] is not a "
hash[sumleft[i]-min] = i; "palindrome\n",
else L, R);
{ }
if ((i - hash[sumleft[i]-
min]) > maxsize) else
{ printf("The Substring [%d
maxsize = i - %d] is not a "
hash[sumleft[i]-min]; "palindrome\n", L,
startindex = R);
hash[sumleft[i]-min] + 1; }
}
} return;
} }
if (maxsize == -1)
printf("No such subarray");
else 4)
printf("%d to %d", startindex,
startindex+maxsize-1); #define MAXN 11

return maxsize; // choices for position


} #define ver 2

// Auxiliary space bounded by a small


3) multiple
// of MAXN, minimizing wastage
void queryResults(string str, Query q[], int hashtable[ver][MAXN];
int m, int n,
unsigned long long int // Array to store possible positions for
prefix[], a key
unsigned long long int int pos[ver];
suffix[],
unsigned long long int /* function to fill hash table with
power[]) dummy value
* dummy value: INT_MIN position for the new key in the
* number of hashtables: ver */ table
void initTable() * If YES: place the new key in its
{ position
for (int j=0; j<MAXN; j++) * and place the older key in an
for (int i=0; i<ver; i++) alternate position
hashtable[i][j] = INT_MIN; for it in the next table */
} if
(hashtable[tableID][pos[tableID]]!=INT_M
/* return hashed value for a key IN)
* function: ID of hash function {
according to which int dis =
key has to hashed hashtable[tableID][pos[tableID]];
* key: item to be hashed */ hashtable[tableID][pos[tableID]]
int hash(int function, int key) = key;
{ place(dis, (tableID+1)%ver,
switch (function) cnt+1, n);
{ }
case 1: return key%MAXN; else //else: place the new key in
case 2: return (key/MAXN)%MAXN; its position
} hashtable[tableID][pos[tableID]]
} = key;
}
/* function to place a key in one of its
possible positions /* function to print hash table contents
* tableID: table in which key has to be */
placed, also equal void printTable()
to function according to which key {
must be hashed printf("Final hash tables:\n");
* cnt: number of times function has
already been called for (int i=0; i<ver; i++,
in order to place the first input key printf("\n"))
* n: maximum number of times function for (int j=0; j<MAXN; j++)
can be recursively (hashtable[i][j]==INT_MIN)?
called before stopping and declaring printf("- "):
presence of cycle */ printf("%d ",
void place(int key, int tableID, int hashtable[i][j]);
cnt, int n)
{ printf("\n");
/* if function has been recursively }
called max number
of times, stop and declare cycle. /* function for Cuckoo-hashing keys
Rehash. */ * keys[]: input array of keys
if (cnt==n) * n: size of input array */
{ void cuckoo(int keys[], int n)
printf("%d unpositioned\n", {
key); // initialize hash tables to a dummy
printf("Cycle present. value (INT-MIN)
REHASH.\n"); // indicating empty position
return; initTable();
}
// start with placing every key at
/* calculate and store possible its position in
positions for the key. // the first hash table according to
* check if key already present at first hash
any of the positions. // function
If YES, return. */ for (int i=0, cnt=0; i<n; i++,
for (int i=0; i<ver; i++) cnt=0)
{ place(keys[i], 0, cnt, n);
pos[i] = hash(i+1, key);
if (hashtable[i][pos[i]] == key) //print the final hash tables
return; printTable();
} }

/* check if another key is already


present at the 5)
int sumoflength(int arr[], int n) 6)
{
// For maintaining distinct int sumoflength(int arr[], int n)
elements. {
unordered_set<int> s; // For maintaining distinct
elements.
// Initialize ending point and unordered_set<int> s;
result
int j = 0, ans = 0; // Initialize ending point and
result
// Fix starting point int j = 0, ans = 0;
for (int i=0; i<n; i++)
{ // Fix starting point
// Find ending point for current for (int i=0; i<n; i++)
subarray with {
// distinct elements. // Find ending point for current
while (j < n && s.find(arr[j]) subarray with
== s.end()) // distinct elements.
{ while (j < n && s.find(arr[j])
s.insert(arr[j]); == s.end())
j++; {
} s.insert(arr[j]);
j++;
// Calculating and adding all }
possible length
// subarrays in arr[i..j] // Calculating and adding all
ans += ((j - i) * (j - i + possible length
1))/2; // subarrays in arr[i..j]
ans += ((j - i) * (j - i +
// Remove arr[i] as we pick new 1))/2;
stating point
// from next // Remove arr[i] as we pick new
s.erase(arr[i]); stating point
} // from next
s.erase(arr[i]);
return ans; }
}
return ans;
}

You might also like