LeetCode:324. Wiggle Sort II

LeetCode:324. Wiggle Sort II

题目描述

Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]…

Example 1:

Input: nums = [1, 5, 1, 1, 6, 4]
Output: One possible answer is [1, 4, 1, 5, 1, 6].

Example 2:

Input: nums = [1, 3, 2, 2, 3, 1]
Output: One possible answer is [2, 3, 1, 3, 1, 2].

Note:
You may assume all input has valid answer.

Follow Up:
Can you do it in O(n) time and/or in-place with O(1) extra space?

解题思路

  1. 找到中位数
  2. 把所有的中位数向中间靠拢
  3. 中位数左右两边各自旋转(尽量别让中位数相遇)
  4. 中位数左边的在偶数位(第 0 位是偶数位),中位数右边的在奇数位

AC 代码

// 通过 partition 找到第 k 个元素(从 0 开始)
func partition(nums []int, k int) {
    if len(nums) <= k || (len(nums) == 1 && k == 0 ) {
        return
    } 
    
    i, j := 0, len(nums)-1
    for i < j {
        for i <= j && nums[i] <= nums[0] { i++ }
        for i <= j && nums[j] > nums[0] { j-- }
        
        if i < j {
            nums[i], nums[j] = nums[j], nums[i]
        }
    }    
    nums[0], nums[j] = nums[j], nums[0]

    if j > k {
        partition(nums[0:j], k)
    } else if j < k {
        partition(nums[j+1:], k-(j+1))
    }
    
}

func middle(nums []int) {
    mid := (len(nums)-1)/2
    
    i, j := 0, mid-1
    for i < j {
        for i < j && nums[i] != nums[mid] { i++ }
        for i < j && nums[j] == nums[mid] { j-- }
        if i < j {
            nums[i], nums[j] = nums[j], nums[i]
        }
    }
    
    i, j = mid+1, len(nums)-1
    for i < j {
        for i < j && nums[i] == nums[mid] { i++ }
        for i < j && nums[j] != nums[mid] { j-- }
        if i < j {
            nums[i], nums[j] = nums[j], nums[i]
        }
    }
}

// [beg, end]
func reverse(nums []int, beg int, end int) {
    for beg <= end {
        nums[beg], nums[end] = nums[end], nums[beg]
        beg++
        end--
    }
}

func wiggleSort(nums []int)  {
    oddPos := len(nums)/2
    
    // 1. 找到中位数
    partition(nums, (len(nums)-1)/2)
    
    // 2. 中位数居中
    middle(nums)
    
    // 3. 左右各自翻转(尽量别让中位数相遇)
    reverse(nums, 0, len(nums)-oddPos-1)
    reverse(nums, len(nums)-oddPos, len(nums)-1)

    // 4. 中位数以前的在偶数位,中位数之后的在奇数位
    right := len(nums)-oddPos
    // 4 3 2 1 8 7 6 5 ==> 4 8 3 7 2 6 1 5
    temp := []int{}
    for i := 0; i < len(nums); i++ {
        temp = append(temp, nums[i])
    }
    for i := 0; i < len(nums); i++ {
        if i % 2 == 0 {
            nums[i] = temp[i/2]
        } else {
            nums[i] = temp[right+i/2]
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值