将整数数组转换为 Zig-Zag 时尚!
让我们再详细说明一下这个问题。基本上,给定一个整数数组,我们需要按照第一个元素小于第二个元素,第二个元素大于第三个元素,第三个元素小于第四个元素,第四个元素大于的顺序排列这个数组第 5 个元素,依此类推。简而言之,输出之字形数组中的元素顺序将是 [1st < 2nd > 3rd < 4th > 5th < 6th > 7th]。因此,如果给定的输入数组是 [4, 3, 7, 8, 6, 2, 1],则之字形数组中的排列之一将是 [3, 7, 4, 8, 2, 6, 1] .
在我们开始思考如何有效地解决它之前,这里有几点值得一提。首先,让我们假设输入数组中的所有元素都是唯一的,即整数不重复。稍后我们也可以包含重复的整数并扩展问题/解决方案。起初,寻找 zig-zag 数组问题看起来类似于排序,但需要注意的是,它不是严格排序。这意味着这个问题可以有多个输出,即对于同一个输入数组,可以找到多个之字形数组,即不止一个解决方案。还有一点需要注意的是,zig-zag 数组可以是 [1st > 2nd < 3rd > 4th < 5th > 6th < 7th]。基本上,重要的是输出中小于 (<) 和大于 (<) 的锯齿形关系,而不是前两个元素的起始顺序。基本上,之字形是 /\/\/\/\/\/ 或 \/\/\/\/\/\。由于以之字形方式排列数组类似于排序,因此这是第一个想到的方法!因此,首先我们可以按升序对数组进行排序,然后我们可以开始交换元素(不包括第一个元素)。让我们通过例子来理解它。输入数组是 [4, 3, 7, 8, 6, 2, 1]。排序后的数组将是 [1, 2, 3, 4, 6, 7, 8]。如果交换第 2 和第 3 个元素,交换第 4 和第 5 个元素,交换第 6 和第 7 个元素,则输出之字形数组将为 [1, 3, 2, 6, 4, 8, 7]。在这里我们可以看到 {1 < 3 > 2 < 6 > 4 < 8 > 7}。由于排序的时间复杂度为 O(nlogn),因此这种转换为 zig-zag 的方法导致 O(nlogn)。让我们看看我们是否可以在这里改进,即是否真的需要第一次排序。
如果我们再想一想,我们会注意到单独成对交换元素会导致 zig-zag 数组。我们实际上只需要遍历数组一次。在遍历数组时,我们可以通过交换元素来设置所需的顺序(即 < 或 >),如果已经不是所需的顺序。为了在程序中实现这一点,让我们维护一个标志来表示需要哪个顺序(即 < 或 >)。如果当前的两个元素不是该顺序,则交换这些元素,否则不交换。让我们深入了解它是如何工作的。假设我们当前正在处理 B 和 C,并且当前关系是 '<' 但我们在输入 [ABC] 中有 B > C - 由于当前关系是 '<' 这意味着先前的关系将是 '>'。所以,关系是 A > B 和 B > C。我们可以推导出 A > C。所以如果我们交换 B 和 C,那么关系是 A > C 和 C < B。最后我们得到了所需的顺序,即 [A < C > B]。由于我们只遍历数组一次,时间复杂度为 O(n)
请参阅此以了解 C++ 实现。