guptaji30's blog

By guptaji30, history, 4 months ago,

Given an array, arr[] of integers. The task is to sort the elements of the given array in the increasing order of their modulo with 3 maintaining the order of their appearance.

Expect time complexity O(N) and the interviewer said that it can be done in only one/two traversal(s)(sorry I don't remember it clearly, it was quite sometime ago).

Expected space complexity O(1).

• +5

 » 4 months ago, # | ← Rev. 3 →   -22 https://en.wikipedia.org/wiki/Dutch_national_flag_problemHowever, stability requirement is not achievable in the given constraints.
 » 4 months ago, # |   -23 We can use dutch national flag as modulo with 3 will leave us with an array of 0, 1, 2. So the problem will boil down to something like this.
•  » » 4 months ago, # ^ |   0 The task is to sort the elements of the given array in the increasing order of their modulo with 3 maintaining the order of their appearance.How to maintain the order of their appearance in one traversal?
•  » » » 4 months ago, # ^ |   0 If you push the elements in a vector, the order will be maintained.
•  » » » » 4 months ago, # ^ | ← Rev. 2 →   0 nvm
•  » » » » » 4 months ago, # ^ |   0 I'll send it in 10 hours, if I don't please remind me :))
•  » » » » 4 months ago, # ^ |   0 Space Complexity is O(1) mate. You can't use another vector. Somehow you have to think of a way while using only swapping.
•  » » » » » 4 months ago, # ^ |   0 You can solve it using single variables, the vecror isn't necessary, and it's indeed with swapping.It's basically swapping if needed, and store the first position of every kind ( 0 1 or 2 ) to be able to make the swaps efficiently
•  » » 4 months ago, # ^ |   0 In that way the original order will not be maintained.
 » 4 months ago, # |   0 Can do it in 2 traversals with no extra space. In one traversal you can get number of 0s,1s and 2s. So in the second traversal, if you encounter a number, you know its exact position (from the previous traversal). Just swap with its exact position and continue the process.
•  » » 4 months ago, # ^ | ← Rev. 2 →   0 can you please elaborate I had though of the same thing but wasn't sure if it will maintain the order of the elements
•  » » » 4 months ago, # ^ |   0 okay, I just gave a thought and found out that the order will not be maintained. If you allow one more traversal then it is possible definitely. In the second traversal replace each value with its original position in the sorted array, this can be done using the number of 0,1,2. Finally, in the 3rd traversal, swap it i.e place everything in the positions stored. Maybe this swapping can be done in the 2nd traversal only efficiently but I guess it's tricky.
•  » » » » 4 months ago, # ^ |   0 Can you write the code for this ??
•  » » » » » 4 months ago, # ^ |   0 Codell n,i; cin>>n; vector v(n); for(i=0;i>v[i]; ll cnt[3]; memset(cnt,0,sizeof(cnt)); for(i=0;i
•  » » » » » » 4 months ago, # ^ |   0 So you are basically storing the appropriate index of the current element by multiplying it with a large number. I had said the same thing to the interviewer but he was not convinced by it.
 » 4 months ago, # |   0 Auto comment: topic has been updated by guptaji30 (previous revision, new revision, compare).
 » 4 months ago, # | ← Rev. 2 →   -13 .
•  » » 4 months ago, # ^ |   +1 Order is not maintained here
 » 4 months ago, # |   +6 I think below code will work assuming input can be modified It uses two passes one to count the number of 0,1,2's and second for modifying the input to make it sorted by starting three pointers from 0,cnt[0],cnt[0]+cnt[1]. code#include using namespace std; #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) #define MOD 1000000007 #define MOD1 998244353 #define INF 1e18 #define nline "\n" #define pb push_back #define ppb pop_back #define mp make_pair #define ff first #define ss second #define PI 3.141592653589793238462 #define set_bits __builtin_popcountll #define sz(x) ((int)(x).size()) #define all(x) (x).begin(), (x).end() typedef long long ll; typedef unsigned long long ull; typedef long double lld; // typedef tree, null_type, less>, rb_tree_tag, tree_order_statistics_node_update > pbds; // find_by_order, order_of_key #ifndef ONLINE_JUDGE #define debug(x) cerr << #x <<" "; _print(x); cerr << endl; #else #define debug(x) #endif void _print(ll t) {cerr << t;} void _print(int t) {cerr << t;} void _print(string t) {cerr << t;} void _print(char t) {cerr << t;} void _print(lld t) {cerr << t;} void _print(double t) {cerr << t;} void _print(ull t) {cerr << t;} template void _print(pair p); template void _print(vector v); template void _print(set v); template void _print(map v); template void _print(multiset v); template void _print(pair p) {cerr << "{"; _print(p.ff); cerr << ","; _print(p.ss); cerr << "}";} template void _print(vector v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} template void _print(set v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} template void _print(multiset v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} template void _print(map v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} int main() { #ifndef ONLINE_JUDGE freopen("Error.txt", "w", stderr); #endif ll n; cin>>n; ll a[n]; ll i; for(i=0;i>a[i]; } ll cnt[3]={0}; for(i=0;i
•  » » 4 months ago, # ^ |   0 I have a doubt.... for example you are changing value of a[oneindx], but you are not storing its previous value i mean it's previous value would be diminshed?
•  » » » 4 months ago, # ^ |   +7 This is very standard technique in which we can store information about two numbers using a single number. let us say some n n=4 and now i want to somehow store 50 also. So first we require some number that is bigger than both 4 and 50 so let us say 51 is one such number so new modified number will be n=4+51*50; now if we need to get information of both number so original number = n%51=(4+51*50)%51=(4%51+(50*51)%51)%51=4%51=4(original number) if we want new number then it is equal to= n/51(integer division)=(4+51*50)/51=0+50=50(second number). so in this we are storing information of two numbers in a single number. 
 » 4 months ago, # |   0 I think the use of stable_partition can surely make the code short and simple, but I am not sure about the number of traversals. Does the use of stable_partition mean traversing the array internally each time?
 » 4 months ago, # |   0 What is wrong with this solution? One traverse, no second array. Returns {0, 3, 3, 4, 10, 4, 2, 8, 5, 8} Code int aa[10] = { 4, 10, 2, 0, 3, 4, 8, 5, 8, 3 }; int idx[3] = { 0, 0, 0 }; int cnt[3] = { 0, 0, 0 }; for (int i = 0; i < 10; i++) { int cur = cnt[0] + cnt[1] + cnt[2]; int b = aa[cur]; int md = b % 3; if (cur != idx[md]) { //swap(aa[idx[md]], aa[cur]); memmove(&aa[idx[md] + 1], &aa[idx[md]], (cur - idx[md]) * sizeof(int)); aa[idx[md]] = b; // do some weird stuff with memmove } cnt[md]++; for (int j = md; j < 3; j++) idx[j]++; } 
 » 4 months ago, # | ← Rev. 4 →   0  int idx = 0; fo(i,0,n){ if(v[i]%3==0){ swap(v[idx++], v[i]); } } fo(i,idx,n){ if(v[i]%3==1){ swap(v[idx++], v[i]); } } Someone plz give an edge case for this codePS- Forget I even asked.