PAT-BASIC1008——陣列元素迴圈右移問題
阿新 • • 發佈:2018-12-16
題目描述:
知識點:陣列
思路:每個位置只移動一次,用一個數組flag來標記該位置是否已經被移動過
如果每次只向右移動一位,那我們對於每個位置就需要移動M次,太浪費時間了。事實上,對於一個位置i,我們是知道其下一個位置將會是(i + M) % N。
我們為什麼要每次只移動1位呢?但是如果一次性移動M位又有個問題,位置i到達位置(i + M) % N,那麼原來(i + M) % N位置的值也將移動到下一個位置,什麼時候其下一個位置剛好是位置i,以此形成一個迴圈呢?
所以,在移動的時候,我們需要一個標記陣列flag來記錄該位置是否已經被移動。在遍歷原陣列移動的時候,如果該位置已經被移動過了,顯然我們不需要再次移動該位置。否則,就移動該位置,並且帶動一系列值一起移動。
時間複雜度是O(N),空間複雜度是O(1)。
C++程式碼:
#include<iostream> #include<vector> using namespace std; int main() { int n; int m; cin >> n >> m; if (m >= n) { m %= n; } vector<int> array; for (int i = 0; i < n; i++) { int temp; cin >> temp; array.push_back(temp); } vector<bool> flag; for (int i = 0; i < n; i++) { flag.push_back(false); } for (int i = 0; i < array.size(); i++) { if (flag[i]) { continue; } flag[i] = true; int temp = array[i]; int index = i; while (true) { int next = index - m; if (next < 0) { next += n; } if (next == i) { array[index] = temp; break; } array[index] = array[next]; flag[next] = true; index = next; } } for (int i = 0; i < array.size(); i++) { cout << array[i]; if (i != array.size() - 1) { cout << " "; } } }
C++解題報告:
JAVA程式碼:
import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int m = scanner.nextInt(); int[] nums = new int[n]; for (int i = 0; i < n; i++) { nums[i] = scanner.nextInt(); } if(m >= n){ m = m % n; } boolean[] flag = new boolean[n]; for (int i = 0; i < n; i++) { if(flag[i]){ continue; } ArrayList<Integer> arrayList = new ArrayList<>(); arrayList.add(i); for (int j = 1;; j++) { if((i + j * m) % n == i){ break; } arrayList.add((i + j * m) % n); } remove(nums, arrayList); for (int j = 0; j < arrayList.size(); j++) { flag[arrayList.get(j)] = true; } } for (int i = 0; i < n; i++) { System.out.print(nums[i]); if(i != n - 1){ System.out.print(" "); } } } private static void remove(int[] nums, ArrayList<Integer> arrayList){ int temp = nums[arrayList.get(arrayList.size() - 1)]; for (int i = arrayList.size() - 1; i >= 1; i--) { nums[arrayList.get(i)] = nums[arrayList.get(i - 1)]; } nums[arrayList.get(0)] = temp; } }
JAVA解題報告: