持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【LeetCode 969. 煎饼排序 】- JavaScript(贪心)
题目描述
给你一个整数数组 arr ,请使用 煎饼翻转 完成对数组的排序。
一次煎饼翻转的执行过程如下:
- 选择一个整数 k ,1 <= k <= arr.length
- 反转子数组 arr[0...k-1](下标从 0 开始)
例如,arr = [3,2,1,4] ,选择 k = 3 进行一次煎饼翻转,反转子数组 [3,2,1] ,得到 arr = [1,2,3,4] 。
以数组形式返回能使 arr 有序的煎饼翻转操作所对应的 k 值序列。任何将数组排序且翻转次数在 10 * arr.length 范围内的有效答案都将被判断为正确。
示例 1:
输入:[3,2,4,1] 输出:[4,2,4,3] 解释: 我们执行 4 次煎饼翻转,k 值分别为 4,2,4,和 3。 初始状态 arr = [3, 2, 4, 1] 第一次翻转后(k = 4):arr = [1, 4, 2, 3] 第二次翻转后(k = 2):arr = [4, 1, 2, 3] 第三次翻转后(k = 4):arr = [3, 2, 1, 4] 第四次翻转后(k = 3):arr = [1, 2, 3, 4],此时已完成排序。
贪心
思路分析:
贪心的思路:主要也是将大问题化解成一个个小问题,而且小问题解法均相似于一种贪婪的期望值。解题思路:核心点在于
i=n~1,先在数组中找到i,然后把i子数组交换把i放到最前面,然后再交换把i放到后面,就好了。具体实现步骤:
先对数组arr进行检验是不是已经有序状态
再对arr数组进行一个反转的操作
再未完成排序的子数组中,需要一个变量来储存最大值经过变换的地址
当还不是有序的情况下,对数组进行遍历,从后往前找到的第一个不满足,arr[i] == i + 1的i,那么当前i就是未排序数组的最后一位,也就是我们要找的最大值,它应该放的位置。如果中间出现最大值了也就停止遍历。
var pancakeSort = function(arr) {
let ans = []
const isSorted = () => {
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) return false
}
return true
}
const pancakeFlip = (idx) => {
for (let i = 0; i <= (idx >>> 1); i++) {
let temp = arr[i]
arr[i] = arr[idx - i]
arr[idx - i] = temp
}
}
while (!isSorted()) {
let targetPos = 0
let maxIdx = 0
for (let i = arr.length - 1; i >= 0; i--) {
if (arr[i] !== i + 1 && targetPos === 0) {
targetPos = i
}
if (targetPos && arr[i] === targetPos + 1) {
maxIdx = i
break
}
}
if (maxIdx === 0) {
ans.push(targetPos + 1)
pancakeFlip(targetPos)
} else {
ans.push(maxIdx + 1, targetPos + 1)
pancakeFlip(maxIdx)
pancakeFlip(targetPos)
}
}
return ans
};
思考
麻了, 早知道不看示例了....看着这道题差点看成要求最短序列了...结果一看题解,NP难...。👀🤞
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤