数组题目:所有蚂蚁掉下来前的最后一刻

题目

标题和出处

标题:所有蚂蚁掉下来前的最后一刻

出处:1503. 所有蚂蚁掉下来前的最后一刻

难度

5 级

题目描述

要求

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

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

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

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

示例

示例 1:

示例 1

输入: n   =   4,   left   =   [4,3],   right   =   [0,1] \texttt{n = 4, left = [4,3], right = [0,1]} n = 4, left = [4,3], right = [0,1]
输出: 4 \texttt{4} 4
解释:如上图所示:

  • 下标 0 \texttt{0} 0 处的蚂蚁命名为 A \texttt{A} A 并向右移动。
  • 下标 1 \texttt{1} 1 处的蚂蚁命名为 B \texttt{B} B 并向右移动。
  • 下标 3 \texttt{3} 3 处的蚂蚁命名为 C \texttt{C} C 并向左移动。
  • 下标 4 \texttt{4} 4 处的蚂蚁命名为 D \texttt{D} D 并向左移动。

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

示例 2:

示例 2

输入: n   =   7,   left   =   [],   right   =   [0,1,2,3,4,5,6,7] \texttt{n = 7, left = [], right = [0,1,2,3,4,5,6,7]} n = 7, left = [], right = [0,1,2,3,4,5,6,7]
输出: 7 \texttt{7} 7
解释:所有蚂蚁都向右移动,下标为 0 \texttt{0} 0 的蚂蚁需要 7 \texttt{7} 7 秒才能从木板上掉落。

示例 3:

示例 3

输入: n   =   7,   left   =   [0,1,2,3,4,5,6,7],   right   =   [] \texttt{n = 7, left = [0,1,2,3,4,5,6,7], right = []} n = 7, left = [0,1,2,3,4,5,6,7], right = []
输出: 7 \texttt{7} 7
解释:所有蚂蚁都向左移动,下标为 7 \texttt{7} 7 的蚂蚁需要 7 \texttt{7} 7 秒才能从木板上掉落。

示例 4:

输入: n   =   9,   left   =   [5],   right   =   [4] \texttt{n = 9, left = [5], right = [4]} n = 9, left = [5], right = [4]
输出: 5 \texttt{5} 5
解释: t   =   1 \texttt{t = 1} t = 1 秒时,两只蚂蚁将回到初始位置,但移动方向与之前相反。

示例 5:

输入: n   =   6,   left   =   [6],   right   =   [0] \texttt{n = 6, left = [6], right = [0]} n = 6, left = [6], right = [0]
输出: 6 \texttt{6} 6

数据范围

  • 1 ≤ n ≤ 10 4 \texttt{1} \le \texttt{n} \le \texttt{10}^\texttt{4} 1n104
  • 0 ≤ left.length ≤ n   +   1 \texttt{0} \le \texttt{left.length} \le \texttt{n + 1} 0left.lengthn + 1
  • 0 ≤ left[i] ≤ n \texttt{0} \le \texttt{left[i]} \le \texttt{n} 0left[i]n
  • 0 ≤ right.length ≤ n   +   1 \texttt{0} \le \texttt{right.length} \le \texttt{n + 1} 0right.lengthn + 1
  • 0 ≤ right[i] ≤ n \texttt{0} \le \texttt{right[i]} \le \texttt{n} 0right[i]n
  • 1 ≤ left.length   +   right.length ≤ n   +   1 \texttt{1} \le \texttt{left.length + right.length} \le \texttt{n + 1} 1left.length + right.lengthn + 1
  • left \texttt{left} left right \texttt{right} right 中的所有值都是唯一的,并且每个值只能出现在二者之一

解法

思路和算法

题目描述中的「当两只向不同方向移动的蚂蚁在某个点相遇时,它们会同时改变移动方向并继续移动」非常具有迷惑性。根据常规思路,需要维护每只蚂蚁的位置和移动方向,当两只移动方向不同的蚂蚁相遇时,更新两只蚂蚁的移动方向。这种做法需要计算每次出现蚂蚁相遇的时间,因此实现是非常麻烦的。

有没有其他实现方法?考虑以下情形:假设有两只蚂蚁, A A A 的位置是 a a a B B B 的位置是 b b b,其中 a < b a<b a<b A A A 向右移动, B B B 向左移动,它们会在位置 c = a + b 2 c=\dfrac{a+b}{2} c=2a+b 相遇,相遇之后,两只蚂蚁同时改变移动方向,即 A A A 向左移动, B B B 向右移动。

上述情形中,从相遇的时刻开始过了时间 Δ t \Delta t Δt 之后, A A A 的位置是 c − Δ t c-\Delta t cΔt B B B 的位置是 c + Δ t c+\Delta t c+Δt。由于每只蚂蚁的移动速度都是相同的,因此如果 A A A B B B 相遇之后按照原来的移动方向继续移动,则从相遇的时刻开始过了时间 Δ t \Delta t Δt 之后, A A A 的位置是 c + Δ t c+\Delta t c+Δt B B B 的位置是 c − Δ t c-\Delta t cΔt。注意到两种情况的区别在于将 A A A B B B 进行了交换。由于这道题只需要知道最后一只蚂蚁从木板上掉下来的时刻,不需要知道每只蚂蚁从木板上掉下来的时刻,因此可以将蚂蚁移动的过程等价地转化成两只蚂蚁相遇后按照原来的移动方向继续移动。

如果一只蚂蚁的初始位置是 x x x,则当这只蚂蚁向左移动时,从木板上掉下来的时刻是 x x x,当这只蚂蚁向右移动时,从木板上掉下来的时刻是 n − x n-x nx

遍历数组 left \textit{left} left right \textit{right} right,分别得到最后一只向左移动的蚂蚁从木板上掉下来的时刻和最后一只向右移动的蚂蚁从木板上掉下来的时刻,其中的最大时刻就是最后一只蚂蚁从木板上掉下来的时刻。

代码

class Solution {
    public int getLastMoment(int n, int[] left, int[] right) {
        int leftLast = 0, rightLast = 0;
        for (int ant : left) {
            leftLast = Math.max(leftLast, ant);
        }
        for (int ant : right) {
            rightLast = Math.max(rightLast, n - ant);
        }
        return Math.max(leftLast, rightLast);
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是木板的长度。需要遍历数组 left \textit{left} left right \textit{right} right 各一次,由于 left \textit{left} left right \textit{right} right 的元素各不相同,因此两个数组的长度之和最大为 n + 1 n+1 n+1,对于两个数组中的每个元素,计算从木板上掉下来的时刻的时间是常数,因此总时间复杂度是 O ( n ) O(n) O(n)

  • 空间复杂度: O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值