3 25 本の整理問題の解説2. アルゴリズムの改善
5432 1
i = 1に立つ→赤い本(ID=1)の本まで歩く→ j = 4
i ≠ j なので入れ替える
i = 2 に立つ→オレンジの本(ID=2)の本まで歩く→ j = 4
i ≠ j なので入れ替える
541 3 2
i = 3 に立つ→黄色の本(ID=3)の本まで歩く→ j = 4
i ≠ j なので入れ替える
541 32
i = 4 に立つ→青色の本(ID=5)の本まで歩く→ j = 4
i = jなので入れ替えない
541 32
挿入ソート的な手順。計算量的には O(N^2 )
3. 本の整理
N = int(input())
A = list(map(int, input().split()))
cnt = 0
for i in range(N-1):
min_index = A.index(min(A[i::]))
if A[i] != A[min_index]:
A[i], A[min_index] = A[min_index], A[i]
cnt += 1
print(cnt)
Pythonのコードはこんな感じ・・・計算量は O(N^2)
N=100000
100000^2だと10000000000 中々厳しい・・・
5. 5432 1 4 1 2 3 5
本の i = 1 を見た時に→オレンジ本のID=2
i = 1 が ID=2では当然交換が必要。
交換対象は ID=1 の本なので位置を確認。
本は ID=1 の本の位置と ID=2 の本の位置の交換
記録は ID=1 の本の記録と ID=2 の本の記録の交換
をする
同じように i = 2 を見た時は
本は ID=2 の本の位置と ID=3 の本の位置を交換
記録は ID=2 の本の位置と ID=3 の本の位置を交換
ID=1の本の位置を確認
1 4 2 3 5
ID=2の本の位置を確認
543 21
……
このようにすると、本の位置を確認する際に順に見る必要がないので交換する位置を O(1) で確認できます。
(先の手順では最大で一番うしろまで順に見るので最悪 O(N) )
よって計算量は O(N) となります。
6. N = int(input())
A = list(map(lambda a: int(a)-1, input().split()))
R = [0]*N
for i in range(N):
R[A[i]] = i
ans = 0
for i in range(N):
if A[i] != i:
tmp = R[i]
R[i], R[A[i]] = R[A[i]], R[i]
A[i], A[tmp] = A[tmp], A[i]
ans += 1
print(ans)
Pythonでのコードは以下の通り