Our job is improving the quality of life, not just delaying death. 

我们要做的是提升生活品质,而非仅仅延缓死亡。

问题描述


难度:中等


有一块木板,长度为n个单位 。一些蚂蚁在木板上移动,每只蚂蚁都以每秒一个单位的速度移动。其中,一部分蚂蚁向左移动,其他蚂蚁向右移动。


当两只向不同方向移动的蚂蚁在某个点相遇时,它们会同时改变移动方向并继续移动。假设更改方向不会花费任何额外时间。


而当蚂蚁在某一时刻t到达木板的一端时,它立即从木板上掉下来。


给你一个整数n和两个整数数组left以及right 。两个数组分别标识向左或者向右移动的蚂蚁在t=0时的位置。请你返回最后一只蚂蚁从木板上掉下来的时刻。


示例 1:

581,所有蚂蚁掉下来前的最后一刻_数组


输入:n = 4, left = [4,3], right = [0,1]

输出:4

解释:如上图所示:

-下标 0 处的蚂蚁命名为 A 并向右移动。

-下标 1 处的蚂蚁命名为 B 并向右移动。

-下标 3 处的蚂蚁命名为 C 并向左移动。

-下标 4 处的蚂蚁命名为 D 并向左移动。

请注意,蚂蚁在木板上的最后时刻是 t = 4 秒,之后蚂蚁立即从木板上掉下来。(也就是说在 t = 4.0000000001 时,木板上没有蚂蚁)。


示例 2:

581,所有蚂蚁掉下来前的最后一刻_前序遍历_02



输入:n = 7, left = [], right = [0,1,2,3,4,5,6,7]

输出:7

解释:所有蚂蚁都向右移动,下标为 0 的蚂蚁需要 7 秒才能从木板上掉落。


示例 3:

581,所有蚂蚁掉下来前的最后一刻_数组_03



输入:n = 7, left = [0,1,2,3,4,5,6,7], right = []

输出:7

解释:所有蚂蚁都向左移动,下标为 7 的蚂蚁需要 7 秒才能从木板上掉落。


示例 4:



输入:n = 9, left = [5], right = [4]

输出:5

解释:t = 1 秒时,两只蚂蚁将回到初始位置,但移动方向与之前相反。


示例 5:



输入:n = 6, left = [6], right = [0]

输出:6



提示:


  • 1<=n<=10^4
  • 0<=left.length<=n+1
  • 0<=left[i]<=n
  • 0<=right.length<=n+1
  • 0<=right[i]<=n
  • 1<=left.length+right.length<=n+1
  • left和right中的所有值都是唯一的,并且每个值只能出现在二者之一中。


问题分析



这题具有很大的迷惑性,当两只蚂蚁相遇的时候需要计算这两只蚂蚁的位置以及方向,当蚂蚁比较多的时候这样计算非常复杂。


题中说了当两只蚂蚁相遇的时候他们同时改变方向,但速度不变。我们可以这样来思考,假设所有蚂蚁都是一样的,并且具有穿透功能。当两只蚂蚁相遇的时候我们可以认为这两只蚂蚁穿透了,依然沿着原来的方向往前走,最终他们会从木板上掉下来,这个时间就是他们各自距离木板边缘的距离(往左边走的蚂蚁距离木板左边的距离,往右边走的蚂蚁距离木板右边的距离)。


如果还不能明白,我们再来这样思考一下。假设有一只蚂蚁往右走,如果没有遇到其他蚂蚁,他会一直往右走。如果遇到其他蚂蚁,在相遇的那一刻他就会改变方向,往左走,原来往左走的改为往右走。我们假设在这一刻他俩交换身体,那么往右走的那个蚂蚁身体还一直往右走,相当于直接穿过去了。后面如果还遇到蚂蚁还可以按照上面的思路……,所以他就会一直往右走。


搞懂了这个过程,这题就简单多了。这题让求的是最后掉落的时间,我们只需要找出往左走的最大时间和往右走的最大时间,取他俩的最大值即可,来看下代码。

 1public int getLastMoment(int n, int[] left, int[] right) {
2 int leftMax = 0;
3 //找出往左边走的最大距离
4 for (int num : left) {
5 leftMax = Math.max(leftMax, num);
6 }
7 int rightMax = 0;
8 //找出往右边走的最大距离
9 for (int num : right) {
10 rightMax = Math.max(rightMax, n - num);
11 }
12 return Math.max(leftMax, rightMax);
13}