陣列迴圈右移

2022-05-28 22:06:11 字數 1571 閱讀 6502

設計乙個演算法,把乙個含有n個元素的陣列迴圈右移k位,要求時間複雜度為o(n),且只允許使用兩個附加變數。

不合題意的解法如下:

我們先試驗簡單的辦法,可以每次將陣列中的元素右移一位,迴圈k次。abcd1234→4abcd123→34abcd12→234abcd1→1234abcd。偽**如下:

**清單2-33

rightshift(int* arr, int n, int k)

while(k--)

int t = arr[n - 1];

for(int i = n - 1; i > 0; i --)

arr[i] = arr[i - 1];

arr[0] = t;

雖然這個演算法可以實現陣列的迴圈右移,但是演算法複雜度為o(k * n),不符合題目的要求,需要繼續往下探索。

假如陣列為abcd1234,迴圈右移4位的話,我們希望到達的狀態是1234abcd。不妨設k是乙個非負的整數,當k為負整數的時候,右移k位,相當於左移(-k)位。左移和右移在本質上是一樣的。

【解法一】

大家開始可能會有這樣的潛在假設,k

仔細觀察迴圈右移的特點,不難發現:每個元素右移n位後都會回到自己的位置上。因此,如果k >n,右移k-n之後的陣列序列跟右移k位的結果是一樣的。進而可得出一條通用的規律:右移k位之後的情形,跟右移k』= k %n位之後的情形一樣。

**清單2-34

rightshift(int* arr, int n, int k)

k %= n;

while(k--)

int t = arr[n - 1];

for(int i = n - 1; i > 0; i --)

arr[i] = arr[i - 1];

arr[0] = t;

可見,增加考慮迴圈右移的特點之後,演算法複雜度降為o(n

2),這跟k無關,與題目的要求又接近了一步。但時間複雜度還不夠低,接下來讓我們繼續挖掘迴圈右移前後,陣列之間的關聯。

【解法二】

假設原陣列序列為abcd1234,要求變換成的陣列序列為1234abcd,即迴圈右移了4位。比較之後,不難看出,其中有兩段的順序是不變的:1234和abcd,可把這兩段看成兩個整體。右移k位的過程就是把陣列的兩部分交換一下。變換的過程通過以下步驟完成:

1.   逆序排列abcd:abcd1234 → dcba1234;

2.   逆序排列1234:dcba1234 → dcba4321;

3.   全部逆序:dcba4321 → 1234abcd。

**清單2-35

reverse(int* arr, int b, int e)

for(; b < e; b++, e--)

int temp = arr[e];

arr[e] = arr[b];

arr[b] = temp;

rightshift(int* arr, int n, int k)

k %= n;

reverse(arr, 0, n – k - 1);

reverse(arr, n - k, n - 1);

reverse(arr, 0, n - 1);

陣列迴圈右移

描述 將乙個長度為 n 的陣列 a 的元素迴圈右移 ror,rotate right k 位,比如陣列 1,2,3,4,5 迴圈右移 3 位之後就變成 3,4,5,1,2。要求 只能用乙個元素大小的附加儲存,元素移動或交換次數為o n 開始時自己想的演算法就是最簡單原始的一種 每次將陣列右移一位,迴...

陣列迴圈右移

設計乙個演算法,把乙個含有n個元素的陣列迴圈右移k位,要求時間複雜度為o n 且只允許使用兩個附加變數。不合題意的解法如下 我們先試驗簡單的辦法,可以每次將陣列中的元素右移一位,迴圈k次。abcd1234 4abcd123 34abcd12 234abcd1 1234abcd。偽 如下 清單2 33...

陣列迴圈右移

本題要求實現乙個對陣列進行迴圈右移的簡單函式 乙個陣列a中存有n 0 個整數,將每個整數迴圈向右移m 0 個位置,即將a中的資料由 a 0 a1 an 1 變換為 an m an 1 a0a1 an m 1 最後m個數迴圈移至最前面的m個位置 函式介面定義 int arrayshift int a,...