Find largest ones after setting a coordinate to oneHow to count the number of set bits in a 32-bit integer?Easy interview question got harder: given numbers 1..100, find the missing number(s) given exactly k are missingFind an integer not among four billion given onesHow to find time complexity of an algorithmFind a vertex ordering of a finite graph GWrite a program to find 100 largest numbers out of an array of 1 billion numbersWraping of equispaced point set in a given directionFinding the largest array index with negative valueReplacing Small Angles in a Polygon with Bigger OnesFinding individual sums of all possible tree after removing edges
Why does the electron wavefunction not collapse within atoms at room temperature in gas, liquids or solids due to decoherence?
What's the "magic similar to the Knock spell" referenced in the Dungeon of the Mad Mage adventure?
A Latin text with dependency tree
Why Faces eat each other?
Program for finding longest run of zeros from a list of 100 random integers which are either 0 or 1
Lorentz invariance of Maxwell's equations in matter
How do carbureted and fuel injected engines compare in high altitude?
Integral with DiracDelta. Can Mathematica be made to solve this?
What's an appropriate age to involve kids in life changing decisions?
Is there an application which does HTTP PUT?
How to avoid making self and former employee look bad when reporting on fixing former employee's work?
Is every story set in the future "science fiction"?
Are there vaccine ingredients which may not be disclosed ("hidden", "trade secret", or similar)?
Is it safe to keep the GPU on 100% utilization for a very long time?
Pre-1993 comic in which Wolverine's claws were turned to rubber?
What are these round pads on the bottom of a PCB?
How to handle DM constantly stealing everything from sleeping characters?
Renting a house to a graduate student in my department
Can the president of the United States be guilty of insider trading?
What replaces x86 intrinsics for C when Apple ditches Intel CPUs for their own chips?
What is the status of the three crises in the history of mathematics?
How is it possible for this circuit to continue functioning correctly?
Passport stamps art, can it be done?
Is there an idiom that means "revealing a secret unintentionally"?
Find largest ones after setting a coordinate to one
How to count the number of set bits in a 32-bit integer?Easy interview question got harder: given numbers 1..100, find the missing number(s) given exactly k are missingFind an integer not among four billion given onesHow to find time complexity of an algorithmFind a vertex ordering of a finite graph GWrite a program to find 100 largest numbers out of an array of 1 billion numbersWraping of equispaced point set in a given directionFinding the largest array index with negative valueReplacing Small Angles in a Polygon with Bigger OnesFinding individual sums of all possible tree after removing edges
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
Interview Question:
You are given a grid of ones and zeros. You can arbitrarily select any point in that grid. You have to write a function which does two things:
- If you choose e.g. coordinate (3,4) and it is zero you need to flip
that to a one. If it is a one you need to flip that to a zero. - You need to return the largest contiguous region
with the most ones i.e. ones have to be at least connected to
another one.
E.g.
[0,0,0,0]
[0,1,1,0]
[1,0,1,0]
We have the largest region being the 3 ones. We have another region which have only one one (found at coordinate (2,0)
).
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
My Solution which has Time Complexity:O(num_row*num_col) each time this function is called:
def get_all_coordinates_of_ones(grid):
set_ones = set()
for i in range(len(grid[0])):
for j in range(len(grid)):
if grid[i][j]:
set_ones.add((i, j))
return set_ones
def get_largest_region(x, y, grid):
num_col = len(grid)
num_row = len(grid[0])
one_or_zero = grid[x][y]
if not grid[x][y]:
grid[x][y] = 1 - grid[x][y]
# get the coordinates of ones in the grid
# Worst Case O(num_col * num_row)
coordinates_ones = get_all_coordinates_of_ones(grid)
while coordinates_ones:
queue = collections.deque([coordinates_ones.pop()])
largest_one = float('-inf')
count_one = 1
visited = set()
while queue:
x, y = queue.popleft()
visited.add((x, y))
for new_x, new_y in ((x, y + 1), (x, y - 1), (x + 1, y), (x - 1, y)):
if (0 <= new_x < num_row and 0 <= new_y < num_col):
if grid[new_x][new_y] == 1 and (new_x, new_y) not in visited:
count_one += 1
if (new_x, new_y) in coordinates_ones:-
coordinates_ones.remove((new_x, new_y))
queue.append((new_x, new_y))
largest_one = max(largest_one, count_one)
return largest_one
My Proposed modifications:
Use Union Find by rank. Encountered a problem. Union all the ones that are adjacent to each other. Now when one of the
coordinates is flipped e.g. from zero to one I will need to remove that coordinate from the region that it is connected to.
Questions are:
- What is the fastest algorithm in terms of time complexity?
- Using Union Find with rank entails removing a node. Is this the way to do improve the time complexity. If so, is there an implementation of removing a node in union find online?
------------------------ EDIT ---------------------------------
Should we always subtract one from the degree from sum(degree-1 of each 'cut' vertex). Here are two examples the first one where we need to subtract one and the second one where we do not need to subtract one:
Block Cut Tree example 1
Cut vertex is vertex B. Degree of vertex B in the block cut tree is 2.
Sum(cardinality of each 'block' vertex) : 2(A,B) + 1(B) + 3 (B,C,D) = 6
Sum(degree of each 'cut' vertex) : 1 (B)
Block cut size: 6 – 1 = 5 but should be 4 (A. B, C, D, E, F). Here need to subtract one more.
Block Cut Tree Example 2
Sum(cardinality of each 'block' vertex) : 3 (A,B,C) + 1(C) + 1(D) + 3 (D, E, F) = 8
Sum(degree of each 'cut' vertex) : 2 (C and D)
Block cut size: 8 – 2 = 6 which is (A. B, C, D, E, F). Here no need to subtract one.
algorithm graph grid breadth-first-search dfs
add a comment |
Interview Question:
You are given a grid of ones and zeros. You can arbitrarily select any point in that grid. You have to write a function which does two things:
- If you choose e.g. coordinate (3,4) and it is zero you need to flip
that to a one. If it is a one you need to flip that to a zero. - You need to return the largest contiguous region
with the most ones i.e. ones have to be at least connected to
another one.
E.g.
[0,0,0,0]
[0,1,1,0]
[1,0,1,0]
We have the largest region being the 3 ones. We have another region which have only one one (found at coordinate (2,0)
).
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
My Solution which has Time Complexity:O(num_row*num_col) each time this function is called:
def get_all_coordinates_of_ones(grid):
set_ones = set()
for i in range(len(grid[0])):
for j in range(len(grid)):
if grid[i][j]:
set_ones.add((i, j))
return set_ones
def get_largest_region(x, y, grid):
num_col = len(grid)
num_row = len(grid[0])
one_or_zero = grid[x][y]
if not grid[x][y]:
grid[x][y] = 1 - grid[x][y]
# get the coordinates of ones in the grid
# Worst Case O(num_col * num_row)
coordinates_ones = get_all_coordinates_of_ones(grid)
while coordinates_ones:
queue = collections.deque([coordinates_ones.pop()])
largest_one = float('-inf')
count_one = 1
visited = set()
while queue:
x, y = queue.popleft()
visited.add((x, y))
for new_x, new_y in ((x, y + 1), (x, y - 1), (x + 1, y), (x - 1, y)):
if (0 <= new_x < num_row and 0 <= new_y < num_col):
if grid[new_x][new_y] == 1 and (new_x, new_y) not in visited:
count_one += 1
if (new_x, new_y) in coordinates_ones:-
coordinates_ones.remove((new_x, new_y))
queue.append((new_x, new_y))
largest_one = max(largest_one, count_one)
return largest_one
My Proposed modifications:
Use Union Find by rank. Encountered a problem. Union all the ones that are adjacent to each other. Now when one of the
coordinates is flipped e.g. from zero to one I will need to remove that coordinate from the region that it is connected to.
Questions are:
- What is the fastest algorithm in terms of time complexity?
- Using Union Find with rank entails removing a node. Is this the way to do improve the time complexity. If so, is there an implementation of removing a node in union find online?
------------------------ EDIT ---------------------------------
Should we always subtract one from the degree from sum(degree-1 of each 'cut' vertex). Here are two examples the first one where we need to subtract one and the second one where we do not need to subtract one:
Block Cut Tree example 1
Cut vertex is vertex B. Degree of vertex B in the block cut tree is 2.
Sum(cardinality of each 'block' vertex) : 2(A,B) + 1(B) + 3 (B,C,D) = 6
Sum(degree of each 'cut' vertex) : 1 (B)
Block cut size: 6 – 1 = 5 but should be 4 (A. B, C, D, E, F). Here need to subtract one more.
Block Cut Tree Example 2
Sum(cardinality of each 'block' vertex) : 3 (A,B,C) + 1(C) + 1(D) + 3 (D, E, F) = 8
Sum(degree of each 'cut' vertex) : 2 (C and D)
Block cut size: 8 – 2 = 6 which is (A. B, C, D, E, F). Here no need to subtract one.
algorithm graph grid breadth-first-search dfs
add a comment |
Interview Question:
You are given a grid of ones and zeros. You can arbitrarily select any point in that grid. You have to write a function which does two things:
- If you choose e.g. coordinate (3,4) and it is zero you need to flip
that to a one. If it is a one you need to flip that to a zero. - You need to return the largest contiguous region
with the most ones i.e. ones have to be at least connected to
another one.
E.g.
[0,0,0,0]
[0,1,1,0]
[1,0,1,0]
We have the largest region being the 3 ones. We have another region which have only one one (found at coordinate (2,0)
).
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
My Solution which has Time Complexity:O(num_row*num_col) each time this function is called:
def get_all_coordinates_of_ones(grid):
set_ones = set()
for i in range(len(grid[0])):
for j in range(len(grid)):
if grid[i][j]:
set_ones.add((i, j))
return set_ones
def get_largest_region(x, y, grid):
num_col = len(grid)
num_row = len(grid[0])
one_or_zero = grid[x][y]
if not grid[x][y]:
grid[x][y] = 1 - grid[x][y]
# get the coordinates of ones in the grid
# Worst Case O(num_col * num_row)
coordinates_ones = get_all_coordinates_of_ones(grid)
while coordinates_ones:
queue = collections.deque([coordinates_ones.pop()])
largest_one = float('-inf')
count_one = 1
visited = set()
while queue:
x, y = queue.popleft()
visited.add((x, y))
for new_x, new_y in ((x, y + 1), (x, y - 1), (x + 1, y), (x - 1, y)):
if (0 <= new_x < num_row and 0 <= new_y < num_col):
if grid[new_x][new_y] == 1 and (new_x, new_y) not in visited:
count_one += 1
if (new_x, new_y) in coordinates_ones:-
coordinates_ones.remove((new_x, new_y))
queue.append((new_x, new_y))
largest_one = max(largest_one, count_one)
return largest_one
My Proposed modifications:
Use Union Find by rank. Encountered a problem. Union all the ones that are adjacent to each other. Now when one of the
coordinates is flipped e.g. from zero to one I will need to remove that coordinate from the region that it is connected to.
Questions are:
- What is the fastest algorithm in terms of time complexity?
- Using Union Find with rank entails removing a node. Is this the way to do improve the time complexity. If so, is there an implementation of removing a node in union find online?
------------------------ EDIT ---------------------------------
Should we always subtract one from the degree from sum(degree-1 of each 'cut' vertex). Here are two examples the first one where we need to subtract one and the second one where we do not need to subtract one:
Block Cut Tree example 1
Cut vertex is vertex B. Degree of vertex B in the block cut tree is 2.
Sum(cardinality of each 'block' vertex) : 2(A,B) + 1(B) + 3 (B,C,D) = 6
Sum(degree of each 'cut' vertex) : 1 (B)
Block cut size: 6 – 1 = 5 but should be 4 (A. B, C, D, E, F). Here need to subtract one more.
Block Cut Tree Example 2
Sum(cardinality of each 'block' vertex) : 3 (A,B,C) + 1(C) + 1(D) + 3 (D, E, F) = 8
Sum(degree of each 'cut' vertex) : 2 (C and D)
Block cut size: 8 – 2 = 6 which is (A. B, C, D, E, F). Here no need to subtract one.
algorithm graph grid breadth-first-search dfs
Interview Question:
You are given a grid of ones and zeros. You can arbitrarily select any point in that grid. You have to write a function which does two things:
- If you choose e.g. coordinate (3,4) and it is zero you need to flip
that to a one. If it is a one you need to flip that to a zero. - You need to return the largest contiguous region
with the most ones i.e. ones have to be at least connected to
another one.
E.g.
[0,0,0,0]
[0,1,1,0]
[1,0,1,0]
We have the largest region being the 3 ones. We have another region which have only one one (found at coordinate (2,0)
).
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
My Solution which has Time Complexity:O(num_row*num_col) each time this function is called:
def get_all_coordinates_of_ones(grid):
set_ones = set()
for i in range(len(grid[0])):
for j in range(len(grid)):
if grid[i][j]:
set_ones.add((i, j))
return set_ones
def get_largest_region(x, y, grid):
num_col = len(grid)
num_row = len(grid[0])
one_or_zero = grid[x][y]
if not grid[x][y]:
grid[x][y] = 1 - grid[x][y]
# get the coordinates of ones in the grid
# Worst Case O(num_col * num_row)
coordinates_ones = get_all_coordinates_of_ones(grid)
while coordinates_ones:
queue = collections.deque([coordinates_ones.pop()])
largest_one = float('-inf')
count_one = 1
visited = set()
while queue:
x, y = queue.popleft()
visited.add((x, y))
for new_x, new_y in ((x, y + 1), (x, y - 1), (x + 1, y), (x - 1, y)):
if (0 <= new_x < num_row and 0 <= new_y < num_col):
if grid[new_x][new_y] == 1 and (new_x, new_y) not in visited:
count_one += 1
if (new_x, new_y) in coordinates_ones:-
coordinates_ones.remove((new_x, new_y))
queue.append((new_x, new_y))
largest_one = max(largest_one, count_one)
return largest_one
My Proposed modifications:
Use Union Find by rank. Encountered a problem. Union all the ones that are adjacent to each other. Now when one of the
coordinates is flipped e.g. from zero to one I will need to remove that coordinate from the region that it is connected to.
Questions are:
- What is the fastest algorithm in terms of time complexity?
- Using Union Find with rank entails removing a node. Is this the way to do improve the time complexity. If so, is there an implementation of removing a node in union find online?
------------------------ EDIT ---------------------------------
Should we always subtract one from the degree from sum(degree-1 of each 'cut' vertex). Here are two examples the first one where we need to subtract one and the second one where we do not need to subtract one:
Block Cut Tree example 1
Cut vertex is vertex B. Degree of vertex B in the block cut tree is 2.
Sum(cardinality of each 'block' vertex) : 2(A,B) + 1(B) + 3 (B,C,D) = 6
Sum(degree of each 'cut' vertex) : 1 (B)
Block cut size: 6 – 1 = 5 but should be 4 (A. B, C, D, E, F). Here need to subtract one more.
Block Cut Tree Example 2
Sum(cardinality of each 'block' vertex) : 3 (A,B,C) + 1(C) + 1(D) + 3 (D, E, F) = 8
Sum(degree of each 'cut' vertex) : 2 (C and D)
Block cut size: 8 – 2 = 6 which is (A. B, C, D, E, F). Here no need to subtract one.
algorithm graph grid breadth-first-search dfs
algorithm graph grid breadth-first-search dfs
edited Apr 7 at 20:57
Meeny
asked Mar 22 at 16:22
MeenyMeeny
83
83
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Without preprocessing:
- Flip the cell in the matrix.
- Consider the matrix as a graph where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components. For each connected component - store its cardinality.
- Return the highest cardinality.
Note that O(V) = O(E) = O(num_row*num_col).
Step 3 takes O(V+E)=O(num_row*num_col), which is similar to your solution.
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
That hints that you can benefit from preprocessing:
Preprocessing:
- Consider the original matrix as a graph G where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components
- Construct the set of block-cut trees (section 5.2) of G (also here, here and here) (one block-cut tree for each connected component of G). Construction: see here.
Processing:
If you flip a '0' cell to '1':
- Find neighbor connected components (0 to 4)
- Remove old block-cut trees, construct a new block-cut tree for the merged component (Optimizations are possible: in some cases, previous tree(s) may be updated instead of reconstructed).
If you flip a '1' cell to '0':
- If this cell is a 'cut' in a block-cut tree:
- remove it from the block-cut-tree
- remove it from each neighbor 'cut' vertex
- split the block-cut-tree into several block-cut trees
- Otherwise (this cell is part of only one 'block vertex')
- remove it from the 'block' vertex; if empty - remove vertex. If block-cut-tree empty - remove it from the set of trees.
The size of a block-cut tree = sum(cardinality of each 'block' vertex) - sum(neighbor_blocks-1 of each 'cut' vertex).
Block-cut trees are not 'well known' as other data structures, so I'm not sure if this is what the interviewer had in mind. If it is - they're really looking for someone well experienced with graph algorithms.
Thank you I will learn read more about it!
– Meeny
Mar 23 at 8:13
Suppose we keep flipping ones to zeroes in a block, we could end up in splitting that into other biconnected component(s). How would this algorithm resolve this? Also, what is this doing: size = [sum(cardinality) of the 'biconnected component' vertices] - [sum(degree-1) of the 'articulation vertex' vertices]
– Meeny
Apr 1 at 19:32
I made some updates. I hope it is clear now.
– Lior Kogan
Apr 2 at 14:07
Do we always need to subtract one from the degree? I have edited my original post to have two examples of the size of the tree.
– Meeny
Apr 7 at 20:58
My bad. Changed degree to neighbor_blocks.
– Lior Kogan
Apr 8 at 17:03
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55303886%2ffind-largest-ones-after-setting-a-coordinate-to-one%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Without preprocessing:
- Flip the cell in the matrix.
- Consider the matrix as a graph where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components. For each connected component - store its cardinality.
- Return the highest cardinality.
Note that O(V) = O(E) = O(num_row*num_col).
Step 3 takes O(V+E)=O(num_row*num_col), which is similar to your solution.
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
That hints that you can benefit from preprocessing:
Preprocessing:
- Consider the original matrix as a graph G where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components
- Construct the set of block-cut trees (section 5.2) of G (also here, here and here) (one block-cut tree for each connected component of G). Construction: see here.
Processing:
If you flip a '0' cell to '1':
- Find neighbor connected components (0 to 4)
- Remove old block-cut trees, construct a new block-cut tree for the merged component (Optimizations are possible: in some cases, previous tree(s) may be updated instead of reconstructed).
If you flip a '1' cell to '0':
- If this cell is a 'cut' in a block-cut tree:
- remove it from the block-cut-tree
- remove it from each neighbor 'cut' vertex
- split the block-cut-tree into several block-cut trees
- Otherwise (this cell is part of only one 'block vertex')
- remove it from the 'block' vertex; if empty - remove vertex. If block-cut-tree empty - remove it from the set of trees.
The size of a block-cut tree = sum(cardinality of each 'block' vertex) - sum(neighbor_blocks-1 of each 'cut' vertex).
Block-cut trees are not 'well known' as other data structures, so I'm not sure if this is what the interviewer had in mind. If it is - they're really looking for someone well experienced with graph algorithms.
Thank you I will learn read more about it!
– Meeny
Mar 23 at 8:13
Suppose we keep flipping ones to zeroes in a block, we could end up in splitting that into other biconnected component(s). How would this algorithm resolve this? Also, what is this doing: size = [sum(cardinality) of the 'biconnected component' vertices] - [sum(degree-1) of the 'articulation vertex' vertices]
– Meeny
Apr 1 at 19:32
I made some updates. I hope it is clear now.
– Lior Kogan
Apr 2 at 14:07
Do we always need to subtract one from the degree? I have edited my original post to have two examples of the size of the tree.
– Meeny
Apr 7 at 20:58
My bad. Changed degree to neighbor_blocks.
– Lior Kogan
Apr 8 at 17:03
|
show 2 more comments
Without preprocessing:
- Flip the cell in the matrix.
- Consider the matrix as a graph where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components. For each connected component - store its cardinality.
- Return the highest cardinality.
Note that O(V) = O(E) = O(num_row*num_col).
Step 3 takes O(V+E)=O(num_row*num_col), which is similar to your solution.
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
That hints that you can benefit from preprocessing:
Preprocessing:
- Consider the original matrix as a graph G where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components
- Construct the set of block-cut trees (section 5.2) of G (also here, here and here) (one block-cut tree for each connected component of G). Construction: see here.
Processing:
If you flip a '0' cell to '1':
- Find neighbor connected components (0 to 4)
- Remove old block-cut trees, construct a new block-cut tree for the merged component (Optimizations are possible: in some cases, previous tree(s) may be updated instead of reconstructed).
If you flip a '1' cell to '0':
- If this cell is a 'cut' in a block-cut tree:
- remove it from the block-cut-tree
- remove it from each neighbor 'cut' vertex
- split the block-cut-tree into several block-cut trees
- Otherwise (this cell is part of only one 'block vertex')
- remove it from the 'block' vertex; if empty - remove vertex. If block-cut-tree empty - remove it from the set of trees.
The size of a block-cut tree = sum(cardinality of each 'block' vertex) - sum(neighbor_blocks-1 of each 'cut' vertex).
Block-cut trees are not 'well known' as other data structures, so I'm not sure if this is what the interviewer had in mind. If it is - they're really looking for someone well experienced with graph algorithms.
Thank you I will learn read more about it!
– Meeny
Mar 23 at 8:13
Suppose we keep flipping ones to zeroes in a block, we could end up in splitting that into other biconnected component(s). How would this algorithm resolve this? Also, what is this doing: size = [sum(cardinality) of the 'biconnected component' vertices] - [sum(degree-1) of the 'articulation vertex' vertices]
– Meeny
Apr 1 at 19:32
I made some updates. I hope it is clear now.
– Lior Kogan
Apr 2 at 14:07
Do we always need to subtract one from the degree? I have edited my original post to have two examples of the size of the tree.
– Meeny
Apr 7 at 20:58
My bad. Changed degree to neighbor_blocks.
– Lior Kogan
Apr 8 at 17:03
|
show 2 more comments
Without preprocessing:
- Flip the cell in the matrix.
- Consider the matrix as a graph where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components. For each connected component - store its cardinality.
- Return the highest cardinality.
Note that O(V) = O(E) = O(num_row*num_col).
Step 3 takes O(V+E)=O(num_row*num_col), which is similar to your solution.
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
That hints that you can benefit from preprocessing:
Preprocessing:
- Consider the original matrix as a graph G where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components
- Construct the set of block-cut trees (section 5.2) of G (also here, here and here) (one block-cut tree for each connected component of G). Construction: see here.
Processing:
If you flip a '0' cell to '1':
- Find neighbor connected components (0 to 4)
- Remove old block-cut trees, construct a new block-cut tree for the merged component (Optimizations are possible: in some cases, previous tree(s) may be updated instead of reconstructed).
If you flip a '1' cell to '0':
- If this cell is a 'cut' in a block-cut tree:
- remove it from the block-cut-tree
- remove it from each neighbor 'cut' vertex
- split the block-cut-tree into several block-cut trees
- Otherwise (this cell is part of only one 'block vertex')
- remove it from the 'block' vertex; if empty - remove vertex. If block-cut-tree empty - remove it from the set of trees.
The size of a block-cut tree = sum(cardinality of each 'block' vertex) - sum(neighbor_blocks-1 of each 'cut' vertex).
Block-cut trees are not 'well known' as other data structures, so I'm not sure if this is what the interviewer had in mind. If it is - they're really looking for someone well experienced with graph algorithms.
Without preprocessing:
- Flip the cell in the matrix.
- Consider the matrix as a graph where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components. For each connected component - store its cardinality.
- Return the highest cardinality.
Note that O(V) = O(E) = O(num_row*num_col).
Step 3 takes O(V+E)=O(num_row*num_col), which is similar to your solution.
You are to find an algorithm that will solve this where you will call that function many times. You need to ensure that your amortized run time is the lowest you can achieve.
That hints that you can benefit from preprocessing:
Preprocessing:
- Consider the original matrix as a graph G where each '1' represents a node, and neighbor nodes are connected with an edge.
- Find all connected components
- Construct the set of block-cut trees (section 5.2) of G (also here, here and here) (one block-cut tree for each connected component of G). Construction: see here.
Processing:
If you flip a '0' cell to '1':
- Find neighbor connected components (0 to 4)
- Remove old block-cut trees, construct a new block-cut tree for the merged component (Optimizations are possible: in some cases, previous tree(s) may be updated instead of reconstructed).
If you flip a '1' cell to '0':
- If this cell is a 'cut' in a block-cut tree:
- remove it from the block-cut-tree
- remove it from each neighbor 'cut' vertex
- split the block-cut-tree into several block-cut trees
- Otherwise (this cell is part of only one 'block vertex')
- remove it from the 'block' vertex; if empty - remove vertex. If block-cut-tree empty - remove it from the set of trees.
The size of a block-cut tree = sum(cardinality of each 'block' vertex) - sum(neighbor_blocks-1 of each 'cut' vertex).
Block-cut trees are not 'well known' as other data structures, so I'm not sure if this is what the interviewer had in mind. If it is - they're really looking for someone well experienced with graph algorithms.
edited Apr 8 at 17:02
answered Mar 22 at 20:51
Lior KoganLior Kogan
15.3k34574
15.3k34574
Thank you I will learn read more about it!
– Meeny
Mar 23 at 8:13
Suppose we keep flipping ones to zeroes in a block, we could end up in splitting that into other biconnected component(s). How would this algorithm resolve this? Also, what is this doing: size = [sum(cardinality) of the 'biconnected component' vertices] - [sum(degree-1) of the 'articulation vertex' vertices]
– Meeny
Apr 1 at 19:32
I made some updates. I hope it is clear now.
– Lior Kogan
Apr 2 at 14:07
Do we always need to subtract one from the degree? I have edited my original post to have two examples of the size of the tree.
– Meeny
Apr 7 at 20:58
My bad. Changed degree to neighbor_blocks.
– Lior Kogan
Apr 8 at 17:03
|
show 2 more comments
Thank you I will learn read more about it!
– Meeny
Mar 23 at 8:13
Suppose we keep flipping ones to zeroes in a block, we could end up in splitting that into other biconnected component(s). How would this algorithm resolve this? Also, what is this doing: size = [sum(cardinality) of the 'biconnected component' vertices] - [sum(degree-1) of the 'articulation vertex' vertices]
– Meeny
Apr 1 at 19:32
I made some updates. I hope it is clear now.
– Lior Kogan
Apr 2 at 14:07
Do we always need to subtract one from the degree? I have edited my original post to have two examples of the size of the tree.
– Meeny
Apr 7 at 20:58
My bad. Changed degree to neighbor_blocks.
– Lior Kogan
Apr 8 at 17:03
Thank you I will learn read more about it!
– Meeny
Mar 23 at 8:13
Thank you I will learn read more about it!
– Meeny
Mar 23 at 8:13
Suppose we keep flipping ones to zeroes in a block, we could end up in splitting that into other biconnected component(s). How would this algorithm resolve this? Also, what is this doing: size = [sum(cardinality) of the 'biconnected component' vertices] - [sum(degree-1) of the 'articulation vertex' vertices]
– Meeny
Apr 1 at 19:32
Suppose we keep flipping ones to zeroes in a block, we could end up in splitting that into other biconnected component(s). How would this algorithm resolve this? Also, what is this doing: size = [sum(cardinality) of the 'biconnected component' vertices] - [sum(degree-1) of the 'articulation vertex' vertices]
– Meeny
Apr 1 at 19:32
I made some updates. I hope it is clear now.
– Lior Kogan
Apr 2 at 14:07
I made some updates. I hope it is clear now.
– Lior Kogan
Apr 2 at 14:07
Do we always need to subtract one from the degree? I have edited my original post to have two examples of the size of the tree.
– Meeny
Apr 7 at 20:58
Do we always need to subtract one from the degree? I have edited my original post to have two examples of the size of the tree.
– Meeny
Apr 7 at 20:58
My bad. Changed degree to neighbor_blocks.
– Lior Kogan
Apr 8 at 17:03
My bad. Changed degree to neighbor_blocks.
– Lior Kogan
Apr 8 at 17:03
|
show 2 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55303886%2ffind-largest-ones-after-setting-a-coordinate-to-one%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown