-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
# Most Stones Removed | ||
|
||
https://www.interviewbit.com/problems/most-stones-removed | ||
|
||
Given a matrix of integers A of size N x 2 describing coordinates of N stones placed in 2D plane. | ||
Now, a move consists of removing a stone that shares a column or row with another stone on the plane. | ||
|
||
Find and return the largest number of moves you can make. | ||
|
||
Note: Each of the N coordinate points contains exactly one stone. | ||
|
||
### Input Format | ||
|
||
The first argument given is the integer matrix A. | ||
|
||
### Output Format | ||
|
||
Return the largest number of moves you can make. | ||
|
||
### Constraints | ||
|
||
``` | ||
1 <= N <= 100000 | ||
0 <= A[i][0], A[i][1] <= 10000 | ||
``` | ||
|
||
### For Example | ||
|
||
``` | ||
Input 1: | ||
A = [ [0, 0] | ||
[0, 1] | ||
[1, 0] | ||
[1, 2] | ||
[2, 2] | ||
[2, 1] ] | ||
Output 1: | ||
5 | ||
Explanation 1: | ||
One of the order of removing stones: | ||
1. Remove (2,1) as it shares row with (2,2) | ||
remaining stones ( (0,0), (0,1), (1,0), (1,2) and (2,2)). | ||
2. Remove (2,2) as it shares column with (1,2) | ||
remaining stones ( (0,0), (0,1), (1,0) and (1,2)). | ||
3. Remove (0,1) as it shares row with (0,0) | ||
remaining stones ( (0,0), (1,0) and (1,2)). | ||
4. Remove (1,2) as it shares row with (1,0) | ||
remaining stones ( (0,0) and (1,0)). | ||
5. Remove (0,0) as it shares column with (1,0) | ||
remaining stones ((1,0)). | ||
So the maximum number of moves is 5. | ||
Input 2: | ||
A = [ [0, 0] | ||
[0, 2] | ||
[2, 0] | ||
[1, 1] | ||
[2, 2] ] | ||
Output 2: | ||
3 | ||
``` | ||
|
||
## Solution Approach | ||
|
||
Let’s say two stones are connected by an edge if they share a row or column. | ||
Every stone belongs to exactly one component, and moves in one component do not affect another component. | ||
Now the answer to the question if finding the number of connected components. | ||
|
||
It can be done in two ways: | ||
|
||
By making graph and Dfs (Time Complexity O(N^2)). | ||
|
||
DSU (Time Complexity ( O(NlogN) ). | ||
|
||
DSU approach: | ||
|
||
Let’s connect row i to column j, which will be represented by j+10000 (so that we have distinct nodes always ). | ||
The answer is the number of components after making all the connections. | ||
|
||
## Solution | ||
### Editorial | ||
```cpp | ||
void init(vector<int> &parent,vector<int> &size){ | ||
for(int i=0; i<parent.size(); ++i){ | ||
parent[i]=i; | ||
size[i]=1; | ||
} | ||
} | ||
|
||
int root(int x,vector<int> &parent){ | ||
while(x!=parent[x]){ | ||
parent[x]=parent[parent[x]]; | ||
x=parent[x]; | ||
} | ||
return x; | ||
} | ||
|
||
void union_by_weight(int x,int y,vector<int> &parent,vector<int> &size){ | ||
x=root(x,parent); | ||
y=root(y,parent); | ||
if(x==y) | ||
return; | ||
if(size[x]>size[y]) | ||
swap(x,y); | ||
size[y]+=size[x]; | ||
size[x]=0; | ||
parent[x]=parent[y]; | ||
} | ||
|
||
int solveit(vector<vector<int>>& stones) { | ||
int N=stones.size(); | ||
if(N==0) | ||
return 0; | ||
vector<int> parent(20000); | ||
vector<int> size(20000); | ||
init(parent,size); | ||
for(auto &stone:stones){ | ||
union_by_weight(stone[0],stone[1]+10000,parent,size); | ||
} | ||
unordered_set<int> s; | ||
for(auto &stone:stones){ | ||
s.insert(root(stone[0],parent)); | ||
} | ||
return N-s.size(); | ||
} | ||
|
||
int Solution::solve(vector<vector<int> > &A) { | ||
return solveit(A); | ||
} | ||
``` | ||
### Fastest | ||
```cpp | ||
void init(vector<int> &parent,vector<int> &size){ | ||
for(int i=0; i<parent.size(); ++i){ | ||
parent[i]=i; | ||
size[i]=1; | ||
} | ||
} | ||
int root(int x,vector<int> &parent){ | ||
while(x!=parent[x]){ | ||
parent[x]=parent[parent[x]]; | ||
x=parent[x]; | ||
} | ||
return x; | ||
} | ||
void union_by_weight(int x,int y,vector<int> &parent,vector<int> &size){ | ||
x=root(x,parent); | ||
y=root(y,parent); | ||
if(x==y) | ||
return; | ||
if(size[x]>size[y]) | ||
swap(x,y); | ||
size[y]+=size[x]; | ||
size[x]=0; | ||
parent[x]=parent[y]; | ||
} | ||
int solveit(vector<vector<int>>& stones) { | ||
int N=stones.size(); | ||
if(N==0) | ||
return 0; | ||
vector<int> parent(20000); | ||
vector<int> size(20000); | ||
init(parent,size); | ||
for(auto &stone:stones){ | ||
union_by_weight(stone[0],stone[1]+10000,parent,size); | ||
} | ||
unordered_set<int> s; | ||
for(auto &stone:stones){ | ||
s.insert(root(stone[0],parent)); | ||
} | ||
return N-s.size(); | ||
} | ||
int Solution::solve(vector<vector<int> > &A) { | ||
return solveit(A); | ||
} | ||
``` | ||
### Lightweight | ||
```cpp | ||
void init(vector<int> &parent,vector<int> &size){ for(int i=0; i<parent.size(); ++i){ parent[i]=i; size[i]=1; } } | ||
|
||
int root(int x,vector<int> &parent){ while(x!=parent[x]){ parent[x]=parent[parent[x]]; x=parent[x]; } return x; } | ||
|
||
void union_by_weight(int x,int y,vector<int> &parent,vector<int> &size) | ||
{ | ||
x=root(x,parent); | ||
y=root(y,parent); | ||
if(x==y) return; | ||
if(size[x]>size[y]) swap(x,y); | ||
size[y]+=size[x]; size[x]=0; | ||
parent[x]=parent[y]; | ||
} | ||
|
||
int solveit(vector<vector<int>>& stones) | ||
{ | ||
int N=stones.size(); | ||
if(N==0) return 0; | ||
vector<int> parent(20000); | ||
vector<int> size(20000); | ||
init(parent,size); | ||
for(auto &stone:stones) | ||
{ | ||
union_by_weight(stone[0],stone[1]+10000,parent,size); | ||
|
||
} | ||
unordered_set<int> s; | ||
for(auto &stone:stones) | ||
{ | ||
s.insert(root(stone[0],parent)); | ||
} | ||
return N-s.size(); | ||
} | ||
|
||
int Solution::solve(vector<vector<int> > &A) { return solveit(A); } | ||
``` | ||
## References | ||
* Taken from https://leetcode.com/articles/most-stones-removed-with-same-row-or-column/ almost verbatim. | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Arrange Cubes | ||
|
||
https://www.interviewbit.com/problems/arrange-cubes/ | ||
|
||
A man has two cubes on his desk. | ||
Every day he arranges both cubes so that the front faces show the current day of the month. | ||
What numbers are on the faces of the cubes to allow this? | ||
|
||
Sort the digits on cube 1 and sort the digits on cube 2 and append them to give the answer. | ||
|
||
For example, if the first cube had digits 1 2 3 4 5 6 and second had digits 3 1 9 8 2 4, | ||
the sorted digits become : | ||
``` | ||
First cube : 1 2 3 4 5 6 | ||
Second cube : 1 2 3 4 8 9 | ||
``` | ||
|
||
So, the answer would be "123456123489" | ||
|
||
|
||
## Solution | ||
|
||
We have two cubes, that means 12 faces or 12 numbers one on each face. The all possible dates are 1 to 31, that includes 11 and 22. So 1 and 2 should be there on both cubes. It means we need 12 digits (0-9 and 1, 2). Now if we see the distribution of numbers on each faces, we have 1 and 2 on both cubes. For 30 we need 0 and 3 on different cubes. So lets say, first cube has 1, 2, 3, 4, 5, 6 and other one has 0, 1, 2, 7, 8, 9. It looks fine, but we we notice, the man uses both the cubes for each day, so how do we show 07, 08, 09 ???So that means we need to have 0 on both the cubes, but that makes it 13, but there are only 12 faces. Thats the trick in this question, we can place cubes upside down too, now which is the number we can use both the ways, yes its 6, it can be used as 9 and then we can have all the possible dates. | ||
|
||
so first cube : 0, 1, 2, 3, 4, 5 | ||
|
||
second cube : 0, 1, 2, 6, 7, 8 | ||
|
||
Answer: 012345012678 |