diff --git a/programming/random/most-stones-removed.md b/programming/random/most-stones-removed.md new file mode 100644 index 0000000..d63a34d --- /dev/null +++ b/programming/random/most-stones-removed.md @@ -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 &parent,vector &size){ + for(int i=0; i &parent){ + while(x!=parent[x]){ + parent[x]=parent[parent[x]]; + x=parent[x]; + } + return x; +} + +void union_by_weight(int x,int y,vector &parent,vector &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>& stones) { + int N=stones.size(); + if(N==0) + return 0; + vector parent(20000); + vector size(20000); + init(parent,size); + for(auto &stone:stones){ + union_by_weight(stone[0],stone[1]+10000,parent,size); + } + unordered_set s; + for(auto &stone:stones){ + s.insert(root(stone[0],parent)); + } + return N-s.size(); +} + +int Solution::solve(vector > &A) { + return solveit(A); +} +``` +### Fastest +```cpp + +void init(vector &parent,vector &size){ + for(int i=0; i &parent){ + while(x!=parent[x]){ + parent[x]=parent[parent[x]]; + x=parent[x]; + } + return x; +} + +void union_by_weight(int x,int y,vector &parent,vector &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>& stones) { + int N=stones.size(); + if(N==0) + return 0; + vector parent(20000); + vector size(20000); + init(parent,size); + for(auto &stone:stones){ + union_by_weight(stone[0],stone[1]+10000,parent,size); + } + unordered_set s; + for(auto &stone:stones){ + s.insert(root(stone[0],parent)); + } + return N-s.size(); +} + +int Solution::solve(vector > &A) { + return solveit(A); +} +``` +### Lightweight +```cpp +void init(vector &parent,vector &size){ for(int i=0; i &parent){ while(x!=parent[x]){ parent[x]=parent[parent[x]]; x=parent[x]; } return x; } + +void union_by_weight(int x,int y,vector &parent,vector &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>& stones) +{ + int N=stones.size(); + if(N==0) return 0; + vector parent(20000); + vector size(20000); + init(parent,size); + for(auto &stone:stones) + { + union_by_weight(stone[0],stone[1]+10000,parent,size); + + } + unordered_set s; + for(auto &stone:stones) + { + s.insert(root(stone[0],parent)); + } + return N-s.size(); +} + +int Solution::solve(vector > &A) { return solveit(A); } +``` + +## References + +* Taken from https://leetcode.com/articles/most-stones-removed-with-same-row-or-column/ almost verbatim. + diff --git a/puzzles/arrange-cubes.md b/puzzles/arrange-cubes.md new file mode 100644 index 0000000..7cc9947 --- /dev/null +++ b/puzzles/arrange-cubes.md @@ -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