煎饼排序是指每次只能翻转前N个节点,完成排序的功能,它的难度在于怎么知道每次应该翻转前几个节点,才能以最快的速度完成排序。
有一种办法是:先从最大的节点开始,将它翻转到最前面(翻转此节点所在位置以及之前的节点),然后再翻转此节点到指定位置上(此节点应该在第几个位置上,就翻转前几个节点,这样这个节点就从第一个位置到指定的这个位置了);依次从大到小,每个节点都处理两次,先移到最前面,再移动到指定位置,这样就完成了煎饼排序的功能。
下面是C++语言实现的功能:
class Solution {
private:
void reversePre(int length, vector<int> &arr, vector<int> &ind) {
for (int i = 0, j = length; i < j; i++, j--) {
int t = ind[arr[i] - 1];
ind[arr[i] - 1] = ind[arr[j] - 1];
ind[arr[j] - 1] = t;
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
public:
vector<int> pancakeSort(vector<int>& arr) {
vector<int> ret;
vector<int> ind(arr.size());
for (int i = 0; i < arr.size(); i++) {
ind[arr[i] - 1] = i;
}
for (int i = arr.size() - 1; i >= 0; i--) {
int curr_max = ind[i]; // 当前最大
if (curr_max == i) {
continue;
}
// cout << curr_max << endl;
if (curr_max > 0) {
ret.push_back(curr_max + 1);
reversePre(curr_max, arr, ind);
// cout << ind[0] << ' ' << ind[1] << ' ' << ind[2] << endl;
// cout << arr[0] << ' ' << arr[1] << ' ' << arr[2] << endl;
}
ret.push_back(i + 1);
reversePre(i, arr, ind);
// cout << arr[0] << ' ' << arr[1] << ' ' << arr[2] << endl;
}
return ret;
}
};