Minimize Maximum Stadium Size - Google Top Interview Questions
Problem Statement :
You are given an integer n and a two-dimensional list of integers views. There are n teams in a tournament and you want to build two stadiums to host the games. Each element in views contains [a, b, people] meaning that when team a and team b compete, there are people number of people that will view that game. The viewership numbers among every pair of teams will be in views. You must permanently assign each team to a stadium. Every team in a stadium plays every other team in that stadium, and only within that stadium. Return the smallest possible maximum capacity of the two stadiums, where the capacity of a stadium is the number of seats required to fit the largest audience of a game in that stadium. Constraints 2 ≤ n ≤ 500 1 ≤ m ≤ 200,000 where m is the length of views Example 1 Input n = 3 views = [ [0, 1, 100], [0, 2, 900], [1, 2, 500] ] Output 100 Explanation We can put teams 0 and 1 in one stadium and team 2 in the other stadium. This means team 2 doesn't have to compete with any other team. Then, for the first stadium we need capacity of 100 to host the game between teams 0 and 1. Example 2 Input n = 2 views = [ [0, 1, 100] ] Output 0 Explanation If we put each team in separate stadiums, then they don't have to compete. Example 3 Input n = 4 views = [ [0, 1, 4], [0, 2, 1], [0, 3, 5], [1, 2, 4], [1, 3, 3], [2, 3, 4] ] Output 3 Explanation We can place teams 0 and 2 in one stadium, and 1 and 3 in the other stadium. In the first stadium, we need capacity of 1 and in the second stadium we need capacity of 3.
Solution :
Solution in C++ :
int n, graph[501][501], which_stadium[501];
bool possible(int team, int stadium, const int& max_people) {
which_stadium[team] = stadium;
for (int i = 0; i < n; i++) {
if (which_stadium[i] != -1 && graph[team][i] > max_people &&
which_stadium[i] != (stadium ^ 1))
return false;
else if (which_stadium[i] == -1 && graph[team][i] > max_people)
if (!possible(i, stadium ^ 1, max_people)) return false;
}
return true;
}
int solve(int n, vector<vector<int>>& views) {
::n = n;
int left = 0, right = 0;
for (auto& v : views) right = max(right, graph[v[0]][v[1]] = graph[v[1]][v[0]] = v[2]);
auto can = [&](int mid) {
fill(which_stadium, which_stadium + n, -1);
for (int i = 0; i < n; i++)
if (which_stadium[i] == -1 && !possible(i, 0, mid)) return false;
return true;
};
while (left < right) {
int mid = left + (right - left) / 2;
if (can(mid))
right = mid;
else
left = mid + 1;
}
return right;
}
Solution in Java :
import java.util.*;
class Solution {
static ArrayList<Integer>[] graph;
public int solve(int N, int[][] views) {
sort(views);
graph = new ArrayList[N];
for (int i = 0; i < N; i++) {
graph[i] = new ArrayList<Integer>();
}
for (int i = views.length - 1; i >= 0; i--) {
// update the graph
graph[views[i][0]].add(views[i][1]);
graph[views[i][1]].add(views[i][0]);
// if there's an odd cycle, its impossible to assign stadiums.
if (!bipartite()) {
return views[i][2];
}
}
return 0;
}
public static boolean bipartite() {
int N = graph.length;
// assign 1-2 colors
int[] color = new int[N];
for (int i = 0; i < N; i++) {
if (color[i] == 0) {
color[i] = 1;
ArrayDeque<Integer> bfs = new ArrayDeque<Integer>();
bfs.add(i);
while (!bfs.isEmpty()) {
int n = bfs.pollFirst();
for (int next : graph[n]) {
if (color[next] == 0) {
color[next] = 3 - color[n];
bfs.add(next);
} else if (color[next] == color[n]) {
return false;
}
}
}
}
}
return true;
}
public static void sort(int[][] arr) {
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
return a[2] - b[2];
// Ascending order.
}
});
}
}
Solution in Python :
class Solution:
def solve(self, n, views):
if n <= 2:
return 0
dist = [[-1] * n for _ in range(n)]
e = collections.defaultdict(list)
for x, y, v in views:
dist[x][y] = v
dist[y][x] = v
def two_colorable(target):
color = [-1] * n
found = False
def go(x, c, target):
for y in range(n):
v = dist[x][y]
if v > target:
if color[x] == color[y]:
nonlocal found
found = True
return
elif color[y] == -1:
color[y] = 1 - c
go(y, 1 - c, target)
for x in range(n):
if color[x] == -1:
color[x] = 1
go(x, 1, target)
if found:
return False
return True
left = 0
right = 10 ** 10
while left < right:
mid = (left + right) // 2
if two_colorable(mid):
right = mid
else:
left = mid + 1
return left
View More Similar Problems
Dynamic Array
Create a list, seqList, of n empty sequences, where each sequence is indexed from 0 to n-1. The elements within each of the n sequences also use 0-indexing. Create an integer, lastAnswer, and initialize it to 0. There are 2 types of queries that can be performed on the list of sequences: 1. Query: 1 x y a. Find the sequence, seq, at index ((x xor lastAnswer)%n) in seqList.
View Solution →Left Rotation
A left rotation operation on an array of size n shifts each of the array's elements 1 unit to the left. Given an integer, d, rotate the array that many steps left and return the result. Example: d=2 arr=[1,2,3,4,5] After 2 rotations, arr'=[3,4,5,1,2]. Function Description: Complete the rotateLeft function in the editor below. rotateLeft has the following parameters: 1. int d
View Solution →Sparse Arrays
There is a collection of input strings and a collection of query strings. For each query string, determine how many times it occurs in the list of input strings. Return an array of the results. Example: strings=['ab', 'ab', 'abc'] queries=['ab', 'abc', 'bc'] There are instances of 'ab', 1 of 'abc' and 0 of 'bc'. For each query, add an element to the return array, results=[2,1,0]. Fun
View Solution →Array Manipulation
Starting with a 1-indexed array of zeros and a list of operations, for each operation add a value to each of the array element between two given indices, inclusive. Once all operations have been performed, return the maximum value in the array. Example: n=10 queries=[[1,5,3], [4,8,7], [6,9,1]] Queries are interpreted as follows: a b k 1 5 3 4 8 7 6 9 1 Add the valu
View Solution →Print the Elements of a Linked List
This is an to practice traversing a linked list. Given a pointer to the head node of a linked list, print each node's data element, one per line. If the head pointer is null (indicating the list is empty), there is nothing to print. Function Description: Complete the printLinkedList function in the editor below. printLinkedList has the following parameter(s): 1.SinglyLinkedListNode
View Solution →Insert a Node at the Tail of a Linked List
You are given the pointer to the head node of a linked list and an integer to add to the list. Create a new node with the given integer. Insert this node at the tail of the linked list and return the head node of the linked list formed after inserting this new node. The given head pointer may be null, meaning that the initial list is empty. Input Format: You have to complete the SinglyLink
View Solution →