大致思路可以:
数组中的元素都不相同
-
- 首先找到最大的数的位置,将其翻转到队首,然后翻转整个数组,最大的数就到队尾了
-
- 然后找到第二大的数,将其翻转到队首,然后翻转除了最大数之外的整个数组,第二大的数也处于对于正确的位置
-
- 以此类推...
根据下图可以更好的理解:
① 对于[3, 2, 4, 1],第一次最大的值是4,首先选择位置k = 3将它翻转至队首,然后选择位置k = 4翻转,此时得到的数组为[1, 3, 2, 4],4已ready。
② 对于[1, 3, 2, 4],不考虑4,3是最大值,将3通过选择k = 2翻转到队首,然后选择位置k = 3(除4之外)翻转队列,得到[2, 1, 3, 4], 此时3已ready。
③ 对于[2, 1, 3, 4],不考虑3、4,2是最大值,2已处于队首,选择位置k = 2翻转到除3,4外最大值的位置,得到[1, 2, 3, 4],排序完成
代码实现的时候,需要考虑:
- 当最大值已处于排序之后的位置,就不需要操作
- 如果处于队首,翻转至队首的操作也可以忽略
注意题目中表明,这个对实现很有帮助
arr中的所有整数互不相同(即,arr是从1到arr.length整数的一个排列)
这个对的
var pancakeSort = function(arr) {
const N = arr.length
// arr是从1到arr.length的一个排列
// 那么第一个最大值应该是 arr.length
let right = N
const result = []
while(right > 0) {
// 如果队尾已是最大值,继续找下一个最大值
if (arr[right - 1] === right) {
right--
continue
}
// 找到最大值的位置
const index = arr.indexOf(right)
if (index !== 0) {
// 如果不在队首,将其翻转到队首
arr = reverseByIdx(arr, index + 1)
result.push(index + 1)
}
// 翻转到队尾
arr = reverseByIdx(arr, right)
// 收集答案
result.push(right)
right--
}
return result
};
// 将array中的[1, idx)进行翻转
const reverseByIdx = (arr, idx) => {
const s = arr.slice(0, idx)
s.reverse()
return s.concat(arr.slice(idx))
}
- 时间复杂度: O(n^2),寻找最大值扫描一次,翻转进行了两次扫描
- 空间复杂度: O(1)