Skip to content

Commit 8a3b8a7

Browse files
committed
seat allocation & mailbox allocation added
1 parent 1973571 commit 8a3b8a7

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed

Array/cinema_seat_allocation.py

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'''
2+
https://leetcode.com/problems/cinema-seat-allocation/
3+
A cinema has n rows of seats, numbered from 1 to n and there are ten seats in each row, labelled from 1 to 10 as shown in the figure above.
4+
Given the array reservedSeats containing the numbers of seats already reserved, for example, reservedSeats[i] = [3,8] means the seat located in row 3 and labelled with 8 is already reserved.
5+
Return the maximum number of four-person groups you can assign on the cinema seats. A four-person group occupies four adjacent seats in one single row. Seats across an aisle (such as [3,3] and [3,4]) are not considered to be adjacent,
6+
but there is an exceptional case on which an aisle split a four-person group, in that case, the aisle split a four-person group in the middle, which means to have two people on each side.
7+
8+
Example 1:
9+
Input: n = 3, reservedSeats = [[1,2],[1,3],[1,8],[2,6],[3,1],[3,10]]
10+
Output: 4
11+
Explanation: The figure above shows the optimal allocation for four groups, where seats mark with blue are already reserved and contiguous seats mark with orange are for one group.
12+
13+
Example 2:
14+
Input: n = 2, reservedSeats = [[2,1],[1,8],[2,6]]
15+
Output: 2
16+
17+
Example 3:
18+
Input: n = 4, reservedSeats = [[4,3],[1,4],[4,6],[1,7]]
19+
Output: 4
20+
'''
21+
22+
from collections import defaultdict
23+
class Solution:
24+
def maxNumberOfFamilies(self, n: int, reservedSeats: List[List[int]]):
25+
group = set()
26+
rows = set()
27+
count = 0
28+
for row, col in reservedSeats:
29+
group.add((row, col))
30+
rows.add(row)
31+
32+
# there are 3 options (but there is overlapping in them)
33+
# for left = 2,3,4,5
34+
# for middle = 4,5,6,7
35+
# for right = 6,7,8,9
36+
for row in rows: # if we run from 1 to n then TLE
37+
left = ((row, 2) not in group) and ((row, 3) not in group) and ((row, 4) not in group) and ((row, 5) not in group)
38+
middle = ((row, 4) not in group) and ((row, 5) not in group) and ((row, 6) not in group) and ((row, 7) not in group)
39+
right = ((row, 6) not in group) and ((row, 7) not in group) and ((row, 8) not in group) and ((row, 9) not in group)
40+
41+
if left and right:
42+
count += 2
43+
elif left or right or middle:
44+
count += 1
45+
46+
# (n - len(rows))*2 = remaining rows not in set and each contribute 2 pairs
47+
return count + ((n - len(rows))*2)
48+
49+
50+
from collections import defaultdict
51+
class Solution:
52+
def maxNumberOfFamilies(self, n: int, reservedSeats: List[List[int]]):
53+
reserved_map = defaultdict(int)
54+
55+
# show each row as 10 bit number
56+
for row, col in reservedSeats:
57+
reserved_map[row] |= (1 << (10-col))
58+
59+
count = 0
60+
61+
right = 15 << 1 # 0000011110
62+
middle = 15 << 3 # 0001111000
63+
left = 15 << 5 # 0111100000
64+
65+
for row in reserved_map:
66+
val = reserved_map[row]
67+
r = val & right
68+
m = val & middle
69+
l = val & left
70+
71+
if (l) == 0 and (r) == 0:
72+
count += 2
73+
elif (l) == 0 or (m) == 0 or (r) == 0:
74+
count += 1
75+
76+
return count + (( n - len(reserved_map))*2)
77+
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'''
2+
https://leetcode.com/problems/allocate-mailboxes/
3+
Given the array houses and an integer k. where houses[i] is the location of the ith house along a street, your task is to allocate k mailboxes in the street.
4+
Return the minimum total distance between each house and its nearest mailbox.
5+
The answer is guaranteed to fit in a 32-bit signed integer.
6+
7+
Example 1:
8+
Input: houses = [1,4,8,10,20], k = 3
9+
Output: 5
10+
Explanation: Allocate mailboxes in position 3, 9 and 20.
11+
Minimum total distance from each houses to nearest mailboxes is |3-1| + |4-3| + |9-8| + |10-9| + |20-20| = 5
12+
13+
Example 2:
14+
Input: houses = [2,3,5,12,18], k = 2
15+
Output: 9
16+
Explanation: Allocate mailboxes in position 3 and 14.
17+
Minimum total distance from each houses to nearest mailboxes is |2-3| + |3-3| + |5-3| + |12-14| + |18-14| = 9.
18+
19+
Example 3:
20+
Input: houses = [7,4,6,1], k = 1
21+
Output: 8
22+
23+
Example 4:
24+
Input: houses = [3,6,14,10], k = 4
25+
Output: 0
26+
'''
27+
28+
class Solution:
29+
def minDistance(self, houses: List[int], k: int):
30+
31+
n = len(houses)
32+
33+
if n <= k:
34+
return 0
35+
36+
def findMin(idx, k):
37+
38+
# if reach end and all mailboxes are placed
39+
if idx == n and k == 0:
40+
return 0
41+
42+
# if not reach end or mailbox are remaining then false case
43+
elif idx == n or k == 0:
44+
return float('inf')
45+
46+
# if already found solution
47+
elif dp[idx][k] != -1:
48+
return dp[idx][k]
49+
50+
ans = float('inf')
51+
# run through all choices of position of 1 mailbox and call for k-1 boxes
52+
for i in range(idx, n):
53+
ans = min(ans, cost[idx][i] + findMin(i+1, k-1))
54+
55+
dp[idx][k] = ans
56+
return ans
57+
58+
max_val = max(houses)
59+
cost = [[0]*(n+1) for _ in range(n+1)]
60+
dp = [[-1]*(n+1) for _ in range(n+1)]
61+
62+
# median works on sorted array so sort
63+
houses.sort()
64+
65+
# i and j represents interval
66+
for i in range(n):
67+
for j in range(i, n):
68+
# (i+j)/2 is median where mail box is placed so find total cost in current interval
69+
for x in range(i, j+1):
70+
cost[i][j] += abs(houses[(i + j)//2] - houses[x])
71+
72+
return findMin(0, k)

0 commit comments

Comments
 (0)