2021/winter interview training for facebook/google
This commit is contained in:
74
puzzles/training/all_possible_subsets.cpp
Normal file
74
puzzles/training/all_possible_subsets.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}"
|
||||
VIM: let b:cf5run="{OUT}"
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
Problem Description
|
||||
For given set of N elements print all possible subsets.
|
||||
|
||||
Sample inputs - Expected outputs
|
||||
{"a"} ->
|
||||
<- empty set
|
||||
a
|
||||
{"a", "b"} ->
|
||||
<- empty set
|
||||
a
|
||||
b
|
||||
a b
|
||||
Input corner cases
|
||||
Empty input set yields to one empty subset.
|
||||
*/
|
||||
|
||||
void printAllSubsets(const std::vector<std::string> &inputSet, std::ostream &os)
|
||||
{
|
||||
std::vector<bool> subset(inputSet.size(), false);
|
||||
|
||||
while (){
|
||||
|
||||
std::cout << '[';
|
||||
for (size_t i = 0; i < inputSet.size(); ++i){
|
||||
if (subset[i]){
|
||||
std::cout << inputSet[i] << ' ';
|
||||
}
|
||||
}
|
||||
std::cout << ']' << std::endl;
|
||||
|
||||
|
||||
std::
|
||||
|
||||
}
|
||||
std::vector<std::string>
|
||||
|
||||
}
|
||||
|
||||
int main ( void )
|
||||
{try{
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
||||
//......
|
||||
const std::vector<std::string> inputSet = {"a", "b", "c", "d"};
|
||||
printAllSubsets(inputSet, std::cout);
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> seconds = end - begin;
|
||||
std::cout << "Time: " << seconds.count() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "std::exception(\"" << e.what() << "\")." << std::endl;
|
||||
return 2;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "unknown exception." << std::endl;
|
||||
return 1;
|
||||
}}
|
||||
89
puzzles/training/array_inversion_count.cpp
Normal file
89
puzzles/training/array_inversion_count.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}"
|
||||
VIM: let b:cf5run="{OUT}"
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <functional>
|
||||
|
||||
/*
|
||||
https://app.codility.com/programmers/lessons/99-future_training/array_inversion_count/
|
||||
|
||||
An array A consisting of N integers is given. An inversion is a pair of indexes (P, Q) such that P < Q and A[Q] < A[P].
|
||||
|
||||
Write a function:
|
||||
|
||||
int solution(vector<int> &A);
|
||||
|
||||
that computes the number of inversions in A, or returns −1 if it exceeds 1,000,000,000.
|
||||
|
||||
For example, in the following array:
|
||||
A[0] = -1 A[1] = 6 A[2] = 3
|
||||
A[3] = 4 A[4] = 7 A[5] = 4
|
||||
|
||||
there are four inversions:
|
||||
(1,2) (1,3) (1,5) (4,5)
|
||||
|
||||
so the function should return 4.
|
||||
|
||||
Write an efficient algorithm for the following assumptions:
|
||||
|
||||
N is an integer within the range [0..100,000];
|
||||
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
|
||||
|
||||
*/
|
||||
|
||||
int solution(const std::vector<int>& v)
|
||||
{
|
||||
std::vector<size_t> iv(v.size(),0);
|
||||
for (size_t i=0; i<v.size(); ++i){
|
||||
iv[i] = i;
|
||||
}
|
||||
std::stable_sort(iv.begin(), iv.end(), [&v](size_t op1, size_t op2){
|
||||
return v[op1] < v[op2];
|
||||
});
|
||||
|
||||
size_t count = 0;
|
||||
for (size_t i=0; i < iv.size(); ++i){
|
||||
if ( i < iv[i]){
|
||||
count += iv[i] - i;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int main ( void )
|
||||
{try{
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
std::cout << solution({-1, 6, 3, 4, 7, 4}) << std::endl;
|
||||
|
||||
std::cout << solution({0, 0, 0, 1, 1, 1}) << std::endl;
|
||||
std::cout << solution({0, 1, 0, 1, 1, 1}) << std::endl;
|
||||
std::cout << solution({0}) << std::endl;
|
||||
std::cout << solution({}) << std::endl;
|
||||
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> seconds = end - begin;
|
||||
std::cout << "Time: " << seconds.count() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "std::exception(\"" << e.what() << "\")." << std::endl;
|
||||
return 2;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "unknown exception." << std::endl;
|
||||
return 1;
|
||||
}}
|
||||
5
puzzles/training/build_and_run_last_changed.sh
Normal file
5
puzzles/training/build_and_run_last_changed.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
SRC=$(ls -t *.cpp | head -1)
|
||||
|
||||
set -x
|
||||
clang -std=c++20 -O2 -pthread -lstdc++ -I. $SRC && ./a.out
|
||||
86
puzzles/training/consolidate_contacts.cpp
Normal file
86
puzzles/training/consolidate_contacts.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}"
|
||||
VIM: let b:cf5run="{OUT}"
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <chrono>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
/*
|
||||
|
||||
std::unordered_map<std::string, std::unordered_set<std::string>>
|
||||
*/
|
||||
|
||||
using contacts_type = std::unordered_map<std::string, std::unordered_set<std::string>>;
|
||||
using emails_type = std::unordered_map<std::string, std::unordered_set<std::string>>;
|
||||
|
||||
|
||||
void
|
||||
all_contacts(
|
||||
const std::string& contact,
|
||||
std::unordered_set<std::string>& visited_contacts,
|
||||
const contacts_type& contacts,
|
||||
const emails_type& emails,
|
||||
std::unordered_set<std::string>& merged_emails)
|
||||
{
|
||||
visited_contacts.insert(contact);
|
||||
for (const auto& email: contacts[contact]){
|
||||
if (merged_emails.count(email)==0){
|
||||
merged_emails.insert(email);
|
||||
for (const auto& merging_contacts : emails[email]){
|
||||
all_contacts(merging_contacts, visited_contacts, contacts, emails, merged_emails );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contacts_type merge( const contacts_type& contacts){
|
||||
|
||||
std::unordered_map<std::string, std::unordered_set<std::string>> emails;
|
||||
|
||||
for (const auto& contact : contacts){
|
||||
for (const auto& email : contact.second){
|
||||
emails[email].insert(contact.first);
|
||||
}
|
||||
}
|
||||
|
||||
contacts_type merged_contacts;
|
||||
std::unordered_set<std::string> visited_contacts;
|
||||
for (const auto& contact : contacts){
|
||||
if (visited_contacts.count(contact.first) == 0){
|
||||
auto& merged_emails = merged_contacts[contact.first];
|
||||
all_contacts(contact.first, visited_contacts, contacts, emails, merged_emails);
|
||||
}
|
||||
}
|
||||
|
||||
return merged_contacts;
|
||||
}
|
||||
|
||||
|
||||
int main ( void )
|
||||
{try{
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
||||
//......
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> seconds = end - begin;
|
||||
std::cout << "Time: " << seconds.count() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "std::exception(\"" << e.what() << "\")." << std::endl;
|
||||
return 2;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "unknown exception." << std::endl;
|
||||
return 1;
|
||||
}}
|
||||
118
puzzles/training/disjoint_intervals.cpp
Normal file
118
puzzles/training/disjoint_intervals.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
[2, 9]
|
||||
[3, 13]
|
||||
[3, 10]
|
||||
[3, 8]
|
||||
[3, 6]
|
||||
[3, 7]
|
||||
[4, 8]
|
||||
[4, 4] *
|
||||
[4, 10]
|
||||
[5, 11]
|
||||
[7, 7] *
|
||||
[7, 8]
|
||||
[7, 12]
|
||||
[7, 15]
|
||||
[9, 12]
|
||||
[9, 10] *
|
||||
|
||||
/*
|
||||
|
||||
Disjoint Intervals (https://www.interviewbit.com/problems/disjoint-intervals/)
|
||||
|
||||
Asked in:
|
||||
Google
|
||||
|
||||
Problem Description
|
||||
|
||||
Given a set of N intervals denoted by 2D array A of size N x 2, the task is to find the length of maximal set of mutually disjoint intervals.
|
||||
|
||||
Two intervals [x, y] & [p, q] are said to be disjoint if they do not have any point in common.
|
||||
|
||||
Return a integer denoting the length of maximal set of mutually disjoint intervals.
|
||||
|
||||
|
||||
|
||||
Problem Constraints
|
||||
|
||||
1 <= N <= 105
|
||||
|
||||
1 <= A[i][0] <= A[i][1] <= 109
|
||||
|
||||
|
||||
|
||||
Input Format
|
||||
|
||||
First and only argument is a 2D array A of size N x 2 denoting the N intervals.
|
||||
|
||||
|
||||
Output Format
|
||||
|
||||
Return a integer denoting the length of maximal set of mutually disjoint intervals.
|
||||
|
||||
|
||||
Example Input
|
||||
|
||||
Input 1:
|
||||
|
||||
A = [
|
||||
[1, 4]
|
||||
[2, 3]
|
||||
[4, 6]
|
||||
[8, 9]
|
||||
]
|
||||
|
||||
Input 2:
|
||||
|
||||
A = [
|
||||
[1, 9]
|
||||
[2, 3]
|
||||
[5, 7]
|
||||
]
|
||||
|
||||
|
||||
|
||||
Example Output
|
||||
|
||||
Output 1:
|
||||
|
||||
3
|
||||
|
||||
Output 2:
|
||||
|
||||
2
|
||||
|
||||
|
||||
|
||||
Example Explanation
|
||||
|
||||
Explanation 1:
|
||||
|
||||
Intervals: [ [1, 4], [2, 3], [4, 6], [8, 9] ]
|
||||
Intervals [2, 3] and [1, 4] overlap.
|
||||
We must include [2, 3] because if [1, 4] is included thenwe cannot include [4, 6].
|
||||
We can include at max three disjoint intervals: [[2, 3], [4, 6], [8, 9]]
|
||||
|
||||
Explanation 2:
|
||||
|
||||
Intervals: [ [1, 9], [2, 3], [5, 7] ]
|
||||
We can include at max two disjoint intervals: [[2, 3], [5, 7]]
|
||||
*/
|
||||
int Solution::solve(vector<vector<int> > &A) {
|
||||
|
||||
std::sort(A.begin(),A.end(),
|
||||
[](const vector<int>& op1, const vector<int>& op2){
|
||||
return (op1[0] < op2[0] );
|
||||
});
|
||||
|
||||
int c = 1;
|
||||
auto it = A.begin();
|
||||
for (auto jt = A.begin()+1; jt != A.end(); ++jt){
|
||||
if (it->at(1) < jt->at(0)){
|
||||
c++;
|
||||
it = jt;
|
||||
} if (jt->at(1) < it->at(1)){
|
||||
it = jt;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
61
puzzles/training/gas_station.cpp
Normal file
61
puzzles/training/gas_station.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
Gas Station
|
||||
|
||||
Asked in:
|
||||
Bloomberg
|
||||
Google
|
||||
DE Shaw
|
||||
Amazon
|
||||
Flipkart
|
||||
|
||||
Given two integer arrays A and B of size N.
|
||||
There are N gas stations along a circular route, where the amount of gas at station i is A[i].
|
||||
|
||||
You have a car with an unlimited gas tank and it costs B[i] of gas to travel from station i
|
||||
to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
|
||||
|
||||
Return the minimum starting gas station’s index if you can travel around the circuit once, otherwise return -1.
|
||||
|
||||
You can only travel in one direction. i to i+1, i+2, … n-1, 0, 1, 2.. Completing the circuit means starting at i and
|
||||
ending up at i again.
|
||||
|
||||
|
||||
|
||||
Input Format
|
||||
|
||||
The first argument given is the integer array A.
|
||||
The second argument given is the integer array B.
|
||||
|
||||
Output Format
|
||||
|
||||
Return the minimum starting gas station's index if you can travel around the circuit once, otherwise return -1.
|
||||
|
||||
For Example
|
||||
|
||||
Input 1:
|
||||
A = [1, 2]
|
||||
B = [2, 1]
|
||||
Output 1:
|
||||
1
|
||||
Explanation 1:
|
||||
If you start from index 0, you can fill in A[0] = 1 amount of gas. Now your tank has 1 unit of gas. But you need B[0] = 2 gas to travel to station 1.
|
||||
If you start from index 1, you can fill in A[1] = 2 amount of gas. Now your tank has
|
||||
*/
|
||||
int Solution::canCompleteCircuit(const vector<int> &A, const vector<int> &B) {
|
||||
int f = 0;
|
||||
int mf = 0;
|
||||
size_t mi = -1;
|
||||
for (size_t i =0; i < A.size(); ++i){
|
||||
f += A[i]-B[i];
|
||||
if (f < mf){
|
||||
mf = f;
|
||||
mi = i;
|
||||
}
|
||||
if ((i+1) == A.size() && f < 0){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return (mi+1) % A.size();
|
||||
}
|
||||
34
puzzles/training/majority_element.cpp
Normal file
34
puzzles/training/majority_element.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Majority Element (https://www.interviewbit.com/problems/majority-element/)
|
||||
|
||||
Asked in:
|
||||
Microsoft
|
||||
Yahoo
|
||||
Google
|
||||
Amazon
|
||||
|
||||
Given an array of size n, find the majority element. The majority element is the element that appears more than floor(n/2) times.
|
||||
|
||||
You may assume that the array is non-empty and the majority element always exist in the array.
|
||||
|
||||
Example :
|
||||
|
||||
Input : [2, 1, 2]
|
||||
Return : 2 which occurs 2 times which is greater than 3/2.
|
||||
|
||||
*/
|
||||
int Solution::majorityElement(const vector<int> &A) {
|
||||
int c =0;
|
||||
int e =0;
|
||||
for (int a : A){
|
||||
if (c == 0){
|
||||
e = a;
|
||||
c++;
|
||||
} else if ( e != a ){
|
||||
c--;
|
||||
} else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
Reference in New Issue
Block a user