1067. Sort with Swap(0,*)

好弱啊,這個題目折騰了很久。

構造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;
}
相關文章
相關標籤/搜索