题目来源:https://leetcode-cn.com/problems/pancake-sorting/
大致题意:
给一个数组,使用翻转对其进行升序排序,翻转规则为:
- 指定索引 i,翻转 0 至 i 的所有元素
记录并返回每次翻转的位置(索引 +1 即为位置)
思路
对于一个元素,使用翻转将其放到末尾需要两步(设元素在索引 x 的位置,数组长度为 n):
- 将 0 - x 的元素翻转
- 将整个数组,也就是 0 - n-1 翻转
那么对于该题,有:
- 遍历 n - 1 轮,每次将当前还未放到末尾的数组最大值通过上述方法放到当前数组末尾
- 每放入一个最大值,就把该元素从数组中去掉,具体地,将下一轮遍历的数组长度 -1 即可
需要注意,有可能最大值本来就在末尾,这样就不用翻转,跳过本轮的翻转操作即可
public class PancakeSort {
public List<Integer> pancakeSort(int[] arr) {
List<Integer> ans = new ArrayList<>();
// 遍历 n-1 轮,每轮遍历的数组长度 -1
for (int n = arr.length; n > 1; n--) {
int idx = 0;
// 找出当前可遍历的数组最大元素
for (int i = 1; i < n; i++) {
if (arr[i] > arr[idx]) {
idx = i;
}
}
// 若最大元素就在当前末尾,跳过
if (idx == n - 1) {
continue;
}
// 两次翻转,将最大元素放到末尾
reverse(arr, idx);
reverse(arr, n - 1);
// 记录翻转位置
ans.add(idx + 1);
ans.add(n);
}
return ans;
}
// 翻转
public void reverse(int[] arr, int end) {
for (int i = 0, j = end; i < j; i++, j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}