構造hash表用來維護各個元素所在的位置,利用map維護一顆紅黑樹來保存還未肯定的元素的位置。ios
(1)用0不斷的跟其餘元素交換,每次交換都會保證一個元素在正確的位置。算法
(2)交換的過程當中可能使得元素0到第0個位置,此時用0與某個還未在正確位置的元素交換。數組
循環(1)(2)直至全部元素都在正確的位置。spa
出現(2)這種狀況的最大次數可能N,由於出現一次這種狀況,必定會在接下來運行(1)的時候保證至少一個元素被交換到正確的位置。綜上所述,最大交換次數應該不會高於2*N,每次交換會維護一次map,因此最終的算法複雜度應該爲O(NlogN).
code
// 1067. Sort with Swap.cpp : 定義控制檯應用程序的入口點。 // #include "stdafx.h" #include <iostream> #include <map> using namespace std; const int N = 100003; int a[N], hashTab[N]; map<int, int> cmap; void swap(int &m1, int &m2){ int temp = m1; m1 = m2; m2 = temp; } int main() { int n, cnt = 0, diff; cin >> n; for(int i = 0; i < n; i++){ cin >> a[i]; hashTab[a[i]] = i; if(i != 0 && a[i] != i) cmap[i] = i; } do{ while(hashTab[0] != 0){ swap(a[hashTab[0]], a[hashTab[hashTab[0]]]); int tmp = hashTab[0]; hashTab[0] = hashTab[hashTab[0]]; hashTab[tmp] = tmp; map<int, int>::iterator mIte = cmap.find(tmp); cmap.erase(mIte); cnt++; } if(cmap.size() != 0){ map<int, int>::iterator mIte = cmap.begin(); cnt++; hashTab[0] = hashTab[mIte -> first]; hashTab[mIte -> first] = 0; swap(a[hashTab[mIte -> first]], a[0]); } } while(cmap.size() != 0); cout << cnt << endl; return 0; }
改進版本:ci
棄用map,維護一個bool數組used[]保存某個元素是否已經肯定好,每當一個元素被肯定下來,就賦值爲true(初始時數組清0)。hash
設置一個在第2步能夠被用來交換的位置swapPos,初始時swapPos=1,由某個元素肯定下來,就要詢問該位置是否和swapPos相等,若是相等,則相應的swapPos後移直至一個還未肯定好的位置pos(即used[pos]==false)。由此觀之,swapPos後移頂多後移N個位置,每次在第二步尋找與0交換的元素,能夠直接用a[swapPos]與之交換。因此最終的算法複雜度應爲O(3*N)。it
// 1067. Sort with Swap.cpp : 定義控制檯應用程序的入口點。 // #include "stdafx.h" #include <iostream> #include <map> using namespace std; const int N = 100003; int a[N], hashTab[N]; bool used[N]; void swap(int &m1, int &m2){ int temp = m1; m1 = m2; m2 = temp; } int main() { int n, cnt = 0; cin >> n; memset(used, 0, sizeof(used)); for(int i = 0; i < n; i++){ cin >> a[i]; hashTab[a[i]] = i; if(a[i] == i) used[i] = true; } int swapPos = 1; while(used[swapPos]) swapPos++; do{ while(hashTab[0] != 0){ swap(a[hashTab[0]], a[hashTab[hashTab[0]]]); int tmp = hashTab[0]; hashTab[0] = hashTab[hashTab[0]]; hashTab[tmp] = tmp; used[tmp] = true; if(tmp == swapPos){ swapPos++; while(used[swapPos]) swapPos++; } cnt++; } if(swapPos != n){ cnt++; hashTab[0] = hashTab[swapPos]; hashTab[swapPos] = 0; swap(a[hashTab[swapPos]], a[0]); } } while(swapPos != n); cout << cnt << endl; return 0; }