算法 之 摆动排序Ⅱ

44 阅读1分钟

题目详情: 给你一个整数数组nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]...的顺序。

示例1: 
输入: nums = [1, 5, 1, 1, 6, 4]
输出:[1, 6, 1, 5, 1, 4]
补充: [1, 4, 1, 5, 1, 6]同样符合题目要求
示例2: 
输入: nums = [1, 3, 2, 2, 3, 1]
输出:[2, 3, 1, 3, 1, 2]

提示:

  • 1 < nums.length <= 5 * 10000
  • 0 < nums[i] <= 5000
  • 要求:输入的 nums 是可以满足要求的

解题思路:

先来个神奇的操作,思路后续补充

思路补充一下🉑

分析:如何实现nums[0] < nums[1] > nums[2] < nums[3]?

  • 对数组排序,从大到小
  • 取最后一个值,我们记作n
  • 取第一个值 或者 中间数向前1个
  • 取n-1个值
  • 取第二个值 或者 中间数向前2个
  • ⬇⬇⬇以此类推
  • 直到把所有的值都取完,结束
const wiggleSort = function(nums) {
    const sort = nums.sort((a, b) => a - b).slice()
    let j = nums.length - 1, i = j >> 1, k = 0
    while(k < sort.length) {
        console.log('i', i)
        console.log('j', j)
        console.log('k', k)
        console.log('k & 1', k & 1)
        nums[k] = (k & 1) ? sort[j--] : sort[i--]
        k++
        console.log('nums', nums)
    }
}
wiggleSort([1, 5, 1, 1, 6, 4])

首先sort排序后是 [1, 1, 1, 4, 5, 6] 这里的 >> 1根据实践我们可以理解为 Math.floor(n / 2), 相当于中位数,就是上面代码中的 i, k & 1 的值会是 0 / 1 交替的变,初始化值 k =0 k & 1 = 0 所以第一次取 sort[i--] i = j >> 1 也就是 中间数向前一个,此时 nums[0] = 1,下一次 k & 1 = 1 所以取sort[j--] 也就是 最后一个 此时 nums[1] = 6, 然后下面依次是 nums[2] = 1 nums[3] = 5 nums[4] = 1 nums[5] = 4 最后 nums是 [ 1, 6, 1, 5, 1, 4 ] 附上每次打印的值,供朋友们理解⭕🆚❌

i 2
j 5
k 0
k & 1 0
nums [ 1, 1, 1, 4, 5, 6 ]
i 1
j 5
k 1
k & 1 1
nums [ 1, 6, 1, 4, 5, 6 ]
i 1
j 4
k 2
k & 1 0
nums [ 1, 6, 1, 4, 5, 6 ]
i 0
j 4
k 3
k & 1 1
nums [ 1, 6, 1, 5, 5, 6 ]
i 0
j 3
k 4
k & 1 0
nums [ 1, 6, 1, 5, 1, 6 ]
i -1
j 3
k 5
k & 1 1
nums [ 1, 6, 1, 5, 1, 4 ]