注意要点:
- 题中,我们需要找到index最小的未归位的数,这里我们可以使用,for循环遍历,但是注意到数组规模为100000,所以如果每次使用从1开始的循环,必然会有超时出现,我们需要用一个k保存结果,k表示,index小于k的数组全部已经排序完毕。所以我们每次从k开始遍历就行。
- 另外,swap的思路有两种
1、
找到数字0所在位置k,再找到数字k所在位置m,swap(a[k],a[m]),循环
2、
找到位置0上的数字x,swap(a[0],a[x]) - 比较得知,方法2时间复杂度大大的优于方法1
满分题解(每次从k开始找未归位的数)
#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<cctype>
#include<algorithm>
using namespace std;
const int maxn = 100005;
int aa[maxn];
int n;
int main() {
//freopen("input.txt", "r", stdin);
cin >> n;
int left = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &aa[i]);
if (i != 0 && aa[i] != i) {
left++;
}
}
int count = 0;
int k = 1;
while (left>0) {
if (aa[0] == 0) {
while (k < n) {
if (aa[k] != k) {
swap(aa[k], aa[0]);
count++;
break;
}
k++;
}
}
while (aa[0]!=0) {
count++;
left--;
swap(aa[0], aa[aa[0]]);
}
}
cout << count;
return 0;
}
19分题解(两个案例超时)(每次都是从1开始遍历找最小的未归位的数)
#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<cctype>
#include<algorithm>
using namespace std;
const int maxn = 100005;
int aa[maxn];
int n;
int main() {
//freopen("input.txt", "r", stdin);
cin >> n;
int left = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &aa[i]);
if (i != 0 && aa[i] != i) {
left++;
}
}
int count = 0;
while (left>0) {
if (aa[0] == 0) {
int x = findminindex();
swap(aa[0], aa[x]);
count++;
}
while (aa[0]!=0) {
count++;
left--;
swap(aa[0], aa[aa[0]]);
}
}
cout << count;
return 0;
}