任务是对循环列表中的项目进行重新排序,如下所示:
LRLLLRLLLRRLLRLLLRRLRLLLRLLRLRLRLRRLLLRRRLRLLRLLRL
所以我们得到一个这样的列表:
RRRRRRLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLRRRRRRRRRRRRRR
或者这个:
LLLLLLLLLLLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRRRRRRLLLLL
将两种类型的项目组合在一起,但这两组的确切位置并不重要。
第一个任务是计算每个组中的项目数,因此我们遍历列表一次,对于上面的示例,结果将是:
#L = 30
#R = 20
然后,简单的蛮力解决方案是将列表中的每个位置视为 L 区域的开始,从位置 0 开始,遍历整个列表并计算每个项目离它应该在的区域的边界:
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRRRRRR <- desired output
LRLLLRLLLRRLLRLLLRRLRLLLRLLRLRLRLRRLLLRRRLRLLRLLRL <- input
< < << < >> > > > >< < <<< > >> >> > <- direction to move
然后我们会认为 L 区从位置 1 开始,并再次进行整个计算:
RLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRRRRR <- desired output
LRLLLRLLLRRLLRLLLRRLRLLLRLLRLRLRLRRLLLRRRLRLLRLLRL <- input
<< < << < >> > > > > < <<< > >> >> > <- direction to move
在计算 L 区每个位置的总步数后,我们将知道哪个位置需要最少的步数。这当然是一种 N2 复杂度的方法。
如果我们可以根据位置 X-1 的 L 区域的计算来计算位置 X 的 L 区域所需的步数(无需再次遍历整个列表),这可能会带来复杂性下到 N。
为此,我们需要跟踪每个区域的每一半中错误项目的数量,以及这四个半区域中错误项目的总步数:
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRRRRRR <- desired output
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>><<<<<<<<<<>>>>>>>>>> <- half-zones
LRLLLRLLLRRLLRLLLRRLRLLLRLLRLRLRLRRLLLRRLRRLLRLLRL <- input
< < << < >> > > > >< < <<< > >> >> > <- direction to move
5 6 5 6 <- wrong items
43 45 25 31 <- required steps
当我们向右移动到下一个位置时,左移区域的总步数会减少该区域的错误项目数,而右移区域的总步数会增加数该区域中的错误项目(因为现在每个项目都离该区域的边缘更近/更远了。
5 6 5 6 <- wrong items
38 51 20 37 <- required steps
但是,我们需要检查四个边界点,看看是否有错误的项目从一个半区移动到另一个半区,并相应地调整项目和步数。
在示例中,作为 L 区第一项的 L 现在已成为 R 区中的最后一项,因此我们将 R> 半区的项和步数增加到 7 和 38。
此外,作为 R 区第一个项目的 L 已成为 L 区的最后一个项目,因此我们将 R
此外,R 区中间的 L 已从 R> 移动到 R 和 R 和 R
RLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRRRRR <- desired output
><<<<<<<<<<<<<<<>>>>>>>>>>>>>>><<<<<<<<<<>>>>>>>>> <- half-zones
LRLLLRLLLRRLLRLLLRRLRLLLRLLRLRLRLRRLLLRRLRRLLRLLRL <- input
>< < << < >> > > > > < <<< < >> >> > <- direction to move
5 6 5 6 <- wrong items
38 51 30 28 <- required steps
因此,当 L 区从位置 0 开始时,所需的总步数是 144,我们计算出当 L 区从位置 1 开始时,总数现在是 147,通过查看在 4 处发生的情况列表中的位置,而不必再次遍历整个列表。
更新
在思考如何实现这一点的同时,我意识到在一个区域中向右移动的错误项目的数量必须与在另一个区域中向左移动的错误项目的数量相同;否则区域之间的边界最终会出现在错误的位置。这意味着 L 和 R 区域不会分成两个长度相等的半区域,并且区域中的“中”点会根据其左右有多少错误项目移动。我仍然认为可以将其转换为具有 O(N) 效率的工作代码,但它可能不像我最初描述的那样简单。