標籤:移動 演算法 數組 迴圈
問題:如何將一個數組迴圈左移或者右移k位? 在下面的解決方案中,
我們以迴圈左移為例。 我們最容易想到的是,將前k個元素複製到一個臨時的數組中,然後將剩下的n-k個元素向左移動k個位置,然後將之前的k個元素複製到剩下的位置。這種方法使用了k個額外的儲存空間。我們想到到另一種方法是,只藉助一個臨時空間,每次只向左移動1位,迴圈k次。這種方法產生了多於的已耗用時間。
前面一篇文章中用程式實現了迴圈右移一個數組的演算法。前面提到的都是比較常規的演算法,下面從其它角度來考慮這一問題: 迴圈數組x其實就是交換數組x的子數組a、b得到b、a。例如假設數組x為int x[]={1,2,3,4,5,6,7,8,9,10}; int a[]={1,2,3,4,5}; int b[]={6,7,8,9,10};那麼將x迴圈左移5位則是x1={6,7,8,9,10,1,2,3,4,5};顯然就將數組a,b交換後進行拼接在一起。當然這裡舉的是特例,是為了方便理解。下面是一般情況的分析:假設數組x為int x[]={1,2,3,4,5,6,7,8,9,10}; int a[]={1,2,3,}; int b[]={4,5,6,7,8,9,10};那麼將x迴圈左移3位則是x1={4,5,6,7,8,9,10,1,2,3};因此移動k位,我們就假設a的大小是k位,剩下是b。如果直接交換,那就和上面提到的第一中方法一樣了。
下面是一種新的交換方法:這裡假設a的元素比b少,則將b分為兩個數組bl,br,其中br與a長度相同,bl為b的左邊部分,br為b的右邊部分。在上面例子中,bl={4,5,6,7},br={8,9,10}。則數組x是由a,bl,br拼接而成。經過左移k位後,結果數組x1是由bl,br,a拼接而成。因此這裡需要進行兩步交換,首先a與br交換,變成br,bl,a;然後br與bl交換,變成bl,br,a。
上面問題的重中之重是進行交換。我們還可以這樣進行交換:我們定義a={1,2,3}的反為a‘{3,2,1}。那麼由ab變成ba,可以通過(a‘b‘)‘得到。因此我們可以寫一個求反的子函數,用於求數組中特定部分元素的反。先對a求反,再對b求反,最後對整體求反,就可以得到結果。這裡需要調用求反子函數3次即可。 本文提到的方法較常規的方法的優點是不用計算移動k位後應該到達的位置。本文提到的方法並不是最好的方法,只是說明我們可以這麼做,遇見一個問題,我們可以找到多種方法解決。本文主要是介紹一種思路,程式比較簡單,就不具體實現了。