将排序数组转换为高低数组

时间:2019-07-20 04:10:21

标签: arrays language-agnostic

面试问题: 给定这种形式的排序数组:

1,2,3,4,5,6,7,8,9

(一个更好的例子是10,20,35,42,51,66,71,84,99,但让我们在上面使用) 无需使用额外的内存或标准库即可将其转换为以下低位形式

1,9,2,8,3,7,4,6,5 

从低到高的形式表示我们使用最小的然后是最高的。然后我们使用第二小的和第二高的。

最初,当他询问时,我使用了辅助数组并使用了2指针方法。我把一个指针放在前面,最后把第二个指针放在前面。然后我将左右数据一一复制到我的新数组中,然后向左移动为左++,向右移动为--right,直到它们交叉或变得相同为止。

此后,他要求我无记忆地做。

我在没有记忆的情况下解决该问题的方法如下。但这令人困惑并且无法正常工作

1) swap 2nd and last in **odd** (pos index 1)
1,2,3,4,5,6,7,8,9 becomes 
1,9,3,4,5,6,7,8,2
then we reach even 
2) swap 3rd and last in **even** (pos index 2 we are at 3 )
1,9,3,4,5,6,7,8,2 becomes (swapped 3 and 2_ )
1,9,2,4,5,6,7,8,3
and then sawp 8 and 3 
1,9,2,4,5,6,7,8,3 becomes 
1,9,2,4,5,6,7,3,8

3) we reach in odd (pos index 3 we are at 4 )
1,9,2,4,5,6,7,3,8
becomes 
1,9,2,8,5,6,7,3,4

4) swap even 5 to last 
and here it becomes wrong 

4 个答案:

答案 0 :(得分:0)

好的,假设在空间常数不变的情况下,我们需要损失一些时间复杂度,以下算法可能在O(n ^ 2)时间复杂度下工作。

我用python写的。我写得很快,因此对任何语法错误都道歉。

chrome://extensions/?errors=<extension-id>

快速说明:

假设给我们的初始列表是:

 # s is the array passed.
def hi_low(s):
   last = len(s)
   for i in range(0, last, 2):
      if s[i+1] == None:
        break

      index_to_swap = last
      index_to_be_swapped = i+1

      while s[index_to_be_swapped] != s[index_to_swap]:
           # write your own swap func here
           swap(s[index_to_swap], s[index_to_swap-1])
           index_to_swap -=1
  return s

因此,在我们的程序中,最初是

   1 2 3 4 5 6 7 8 9

表示它指向9,而

     index_to_swap = last

是i + 1,即比当前循环指针领先一步。 [也请记住,我们的循环差为2]。

所以最初,

     index_to_be_swapped = i+1

,在内部循环中,我们要检查的是:直到这两个索引中的值相同,我们才继续进行交换        swap(s [index_to_swap],s [index_to_swap-1])

因此它看起来像:

     i = 0
     index_to_be_swapped = 1
     index_to_swap = 9

现在,完成了内部循环的工作,并使用再次运行主循环

   # initially:
    1 2 3 4 5 6 7 8 9
      ^             ^---index_to_swap
      ^-----index_to_be_swapped

    # after 1 loop
   1 2 3 4 5 6 7 9 8
     ^           ^-----index_to_swap
     ^----- index_to_be_swapped

   ... goes on until

   1 9 2 3 4 5 6 7 8
     ^-----index_to_swap
     ^-----index_to_be_swapped

此过程一直持续到2。

因此,外循环运行几乎n \ 2次,在最坏的情况下,内循环对于每个外循环运行几乎n \ 2次,因此如果n / 2 * n / 2 = n ^ 2,则时间复杂度/ 4,即n ^ 2的阶数,即O(n ^ 2)。

如果有任何错误,请随时指出。 希望这会有所帮助!

答案 1 :(得分:0)

它将适用于任何排序的数组

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

let i = arr[0];
let j = arr[arr.length - 1];
let k = 0;

while(k < arr.length) {
  arr[k] = i;
  if(arr[k+1]) arr[k+1] = j;
  i++;
  k += 2;
  j--; 
}

console.log(arr);

说明:由于它是一个排序数组,因此您需要知道3件事才能产生预期的输出。

  1. 起始值:let i = arr[0]
  2. 结束值(您也可以通过数组的长度找到它):let j = arr[arr.length -1]
  3. 数组长度:arr.length

遍历数组并像这样设置值

arr[firstIndex] = firstValue, arr[thirdIndex] = firstValue + 1 and so on..

arr[secondIndex] = lastValue, arr[fourthIndex] = lastValue - 1 and so on..

很显然,您可以用不同的方式来做相同的事情。但是我认为这是最简单的方法。

答案 2 :(得分:0)

让我首先指出,即使寄存器也是一种存储器。没有任何“额外”内存(除了已排序数组所占用的内存之外),我们什至没有计数器!也就是说,去了:

an > 2个正整数的数组,这些数组按升序排序,位置从0n-1索引。

i = 1n-2,对子数组进行泡沫排序,范围从位置i到位置n-1(包括端值),包括降序和升序。 (这意味着如果i为奇数,则按降序对气泡进行排序,如果为偶数,则按升序对气泡进行排序。)

由于与bubble-sort相比,您只需要比较并可能交换相邻的元素,就不需要“额外的”内存。

(请注意,如果您从i = 0开始并首先以升序排序,则您甚至都不需要a进行预排序。)

还有另一件事:由于您的问题中没有提及,我将对上述算法的性能保持沉默...

答案 3 :(得分:0)

我们将进行n / 2次传递,并且在每次传递过程中,我们将从左至右交换每个元素,从位置2k-1的元素开始,与最后一个元素交换。示例:

  pass 1
  V
1,2,3,4,5,6,7,8,9
1,9,3,4,5,6,7,8,2
1,9,2,4,5,6,7,8,3
1,9,2,3,5,6,7,8,4
1,9,2,3,4,6,7,8,5
1,9,2,3,4,5,7,8,6
1,9,2,3,4,5,6,8,7
1,9,2,3,4,5,6,7,8

      pass 2
      V
1,9,2,3,4,5,6,7,8
1,9,2,8,4,5,6,7,3
1,9,2,8,3,5,6,7,4
1,9,2,8,3,4,6,7,5
1,9,2,8,3,4,5,7,6
1,9,2,8,3,4,5,6,7

          pass 3
          V
1,9,2,8,3,4,5,6,7
1,9,2,8,3,7,5,6,4
1,9,2,8,3,7,4,6,5
1,9,2,8,3,7,4,5,6

              pass 4
              V
1,9,2,8,3,7,4,5,6
1,9,2,8,3,7,4,6,5

这应该进行O(n ^ 2)交换,并且除了所涉及的计数器之外,不使用额外的内存。

要证明的循环不变性是循环的迭代k之后,前2k + 1个位置是正确的。