Foreword
A few days ago, a buddy sent me a link to a LeetCode title, followed by his own submission record, one 2ms
, the other 1451ms
...
At first glance, this question is a bit interesting. Different ideas have so much time difference. Engage in it.
Title description
Here is n
a flight, they are numbered from 1
to n
.
Here we have a flight booking a table in which the first i
strip book record bookings[i] = [i, j, k]
means that we from i
the j
reservation on each flight k
seats.
Please return an n
array of length and answer
return the number of seats reserved on each flight in the order of flight number.
Examples:
Input: bookings = [[1,2,10], [2,3,20], [2,5,25]], n = 5
Output: [10,55,45,25,25]
O (m * n) solution
According to the title, initialize n
an answer
array of length , representing 1
the n
number of seats reserved for the arrival flight, traversing the outer layer, traversing the bookings
inner layer bookings[i] = [i, j, k]
, and calculating the number of seats i
to j
the flight number, that is, the current number of seats plus k
.
public int[] corpFlightBookings(
int[][] bookings, int n) {
int[] answer = new int[n];
// 遍历整个bookings数组
for (int[] b : bookings) {
// 内层循环把每个航班预订数加上
for (int i = b[0] - 1;
i <= b[1] - 1; i++) {
answer[i] += b[2];
}
}
return answer;
}
O (n) solution
Thinking
O(m*n)
The key point in the solution is that we have repeatedly [i, j]
added the inner loop in between k
, how to turn this loop into O(1)
a key to the problem!
[i, j]
Plus k
, this reminds me of the arithmetic sequence. Isn't this k
the arithmetic sequence of tolerance ? and then?
analysis
Let us answer[i]
indicate the i
number of seats reserved for the first flight. Define a difference array d[]
that d[i]
represents the i
difference between the first flight and the i-1
reserved seat of the first flight, ie d[i] = answer[i] - answer[i - 1]
.
In this way, every time we traversed bookings[i] = [i, j, k]
, we only need to d[i]
increase k
, d[j + 1]
decrease k
can be, because i
to j
between flight reservation number is not changed.
Finally, calculate answer[i] = answer[i - 1] + d[i]
and return answer
.
Deduction
Well, this may not be understood by anyone. Let's deduce once according to the example of the topic:
- Initial flight reservation quantity array
answer = [0,0,0,0,0]
, difference arrayd = [0,0,0,0,0]
- When traversing
bookings[0] = [1,2,10]
, the first bit of the difference array is increased by 10, and the third bit is decreased by 10, becomingd = [10,0,-10,0,0]
- Similarly, when traversed
bookings[1] = [2,3,20]
, the difference array becomesd = [10,20,-10,-20,0]
- When the traversal is reached
bookings[2] = [2,5,25]
, the difference array becomesd = [10,45,-10,-20,0]
, the sixth bit is reduced by 25, and we do n’t need it. - Finally, calculate the
answer
value of theanswer[0] = d[0] = 10
array,answer[1] = d[1] + answer[0] = 45 + 10 = 55
, ,answer[2] = d[2] + answer[1] = -10 + 55 = 45
... - Finally, I found that I only need to apply for an array to represent the
d[]
sumanswer[]
, over!
Code
public int[] corpFlightBookings(
int[][] bookings, int n) {
int[] answer = new int[n];
// 遍历bookings 计算航班i+1 对航班i 变化的预订数
for (int[] b : bookings) {
// 增加的预订数
answer[b[0] - 1] += b[2];
// 防止数组越界
if (b[1] < n) {
// 减少的预订数量
answer[b[1]] -= b[2];
}
}
// 航班i的预订数等于,i-1的预订数,加i时刻变化的预定数
for (int i = 1; i < n; i++) {
answer[i] += answer[i - 1];
}
return answer;
}
Carpool
Do you think this is over? Don't be too naive. Take another look at this question, maybe it will bring you new ideas.
Title description
Suppose you are a driver ride, the car initially capacity
empty seats can be used to carry passengers. Due to road restrictions, the car can only travel in one direction (that is, it is not allowed to turn around or change direction, you can imagine it as a vector).
Here is a travel schedule trips[][]
, which trips[i] = [num_passengers, start_location, end_location]
includes your first i
time trip information:
The number of passengers that must be picked up;
the place where
passengers get on; and the place where passengers get off.
These given location locations are the distances required to travel forward from your initial starting location to these locations (they must be in your direction of travel).
You according to the number of seats given travel schedule and the car to determine whether your car can complete the task transfers used by passengers smoothly (if and only if you can pick all passengers at any given trip, return true
, Otherwise please return false
).
Example 1:
Input: trips = [[2,1,5], [3,3,7]], capacity = 4
Output: false
Example 2:
Input: trips = [[2,1,5], [3,3,7]], capacity = 5
Output: true
prompt:
- You can assume that passengers will consciously abide by the good quality of "first down then up"
trips.length <= 1000
1 <= trips[i][0] <= 100
Topic analysis
This question is actually asking whether the number of seats in the car can meet i
the passengers of each trip , that is, each passenger sits on the seat and returns true
if it can , otherwise it returns false
.
If we can calculate the itinerary i
, the number of passengers to take the bus, and then capacity
compare with it, we can get the answer.
Obviously, the number of passengers to board the vehicle = the number of original passengers on the vehicle-the number of passengers getting off the vehicle + the number of passengers getting on the vehicle .
Ideas
We can use arrays or maps to record the itinerary i
, the number of passengers getting off and the number of passengers getting on the bus, and then starting and ending the trip, calculating the number of passengers to be boarded and capacity
compared with it.
Code to implement Map version
public boolean carPooling(
int[][] trips, int capacity) {
// 使用TreeMap 是为了让元素根据key排序
TreeMap<Integer, Integer> map =
new TreeMap<>();
for (int[] t : trips) {
int v = map.getOrDefault(t[1], 0) + t[0];
// 上车乘客数量
map.put(t[1], v);
v = map.getOrDefault(t[2], 0) - t[0];
// 下车乘客数量
map.put(t[2], v);
}
int cur = 0;
for (Map.Entry<Integer, Integer> entry
: map.entrySet()) {
Integer value = entry.getValue();
// 当前数量=之前数量+变化的数量
cur += value;
if (cur > capacity) {
return false;
}
}
return true;
}
Code to implement the array version
public boolean carPooling(
int[][] trips, int capacity) {
// 最远行程 数组长度
int max = 0;
for (int[] t : trips) {
max = Math.max(max, t[2]);
}
// 所有要乘车的乘客数量
int[] passengers = new int[max + 1];
for (int[] t : trips) {
passengers[t[1]] += t[0];
passengers[t[2]] -= t[0];
}
int cur = 0;
for (int passenger : passengers) {
// 当前数量 = 之前数量 + 变化的数量
cur += passenger;
if (cur > capacity) {
return false;
}
}
return true;
}
Look back
The code and scenes of carpooling are easier to understand, because we are like this in life. We can get off first and then get on. It depends on how many people there are in the car and how many people get off the car.
We come back to look at the question of flight booking statistics, which is actually the same problem as carpooling .
I saw someone asking, when calculating the bookings[i] = [i, j, k]
number of reservation changes, why is the first j + 1
position to be subtracted k
, not j
the position? Because j - 1
of the location, airline reservations number of seats should be added k
, and j
location, flight reservations also increase the number of seats k
, so j
and j - 1
the number is between no change. However, j + 1
the number of location flights is no longer added k
, so the number of reservations j + 1
relative to j
location flights is reduced k
.
The problem of carpooling is that trips[i][j]
, at the j
location, when the car arrives at the station, the passenger gets out of the car and takes another stop to pass the station ...
In short, the two questions are essentially the same in nature, only slightly different in details.
Welcome to pay attention to the personal WeChat public account [such as sailing against the current], and carefully output the series of articles on basics, algorithms, and source code.