2021-11-05:摆动排序 II。给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。你可以假设所有输入数组都可以
2021-11-05:摆动排序 II。给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]… 的顺序。你可以假设所有输入数组都可以得到满足题目要求的结果。力扣324。
福大大 答案2021-11-05:
需要了解快排和完美洗牌问题。
时间复杂度:O(N)。
空间复杂度:O(1)。
代码用golang编写。代码如下:
package main
import (
"fmt"
"math/rand"
)
func main() {
nums := []int{1, 5, 1, 1, 6, 4}
wiggleSort(nums)
fmt.Println(nums)
}
// 时间复杂度O(N),额外空间复杂度O(1)
func wiggleSort(nums []int) {
if len(nums) < 2 {
return
}
N := len(nums)
// 小 中 右
findIndexNum(nums, 0, len(nums)-1, N/2)
if (N & 1) == 0 {
// R L -> L R
shuffle(nums, 0, len(nums)-1)
// R1 L1 R2 L2 R3 L3 R4 L4
// L4 R4 L3 R3 L2 R2 L1 R1 -> 代码中的方式,可以的!
// L1 R1 L2 R2 L3 R3 L4 R4 -> 课上的分析,是不行的!不能两两交换!
reverse(nums, 0, len(nums)-1)
// 做个实验,如果把上一行的code注释掉(reverse过程),然后跑下面注释掉的for循环代码
// for循环的代码就是两两交换,会发现对数器报错,说明两两交换是不行的, 必须整体逆序
// for (int i = 0; i < nums.length; i += 2) {
// swap(nums, i, i + 1);
// }
} else {
shuffle(nums, 1, len(nums)-1)
}
}
func findIndexNum(arr []int, L int, R int, index int) int {
pivot := 0
var range2 []int
for L < R {
//pivot = arr[L+(int)(Math.random()*(R-L+1))]
pivot = arr[L+rand.Intn(R-L+1)]
range2 = partition(arr, L, R, pivot)
if index >= range2[0] && index <= range2[1] {
return arr[index]
} else if index < range2[0] {
R = range2[0] - 1
} else {
L = range2[1] + 1
}
}
return arr[L]
}
func partition(arr []int, L int, R int, pivot int) []int {
less := L - 1
more := R + 1
cur := L
for cur < more {
if arr[cur] < pivot {
less++
//swap(arr, ++less, cur++);
arr[less], arr[cur] = arr[cur], arr[less]
cur++
} else if arr[cur] > pivot {
more--
//swap(arr, cur, --more);
arr[more], arr[cur] = arr[cur], arr[more]
} else {
cur++
}
}
return []int{less + 1, more - 1}
}
func shuffle(nums []int, l int, r int) {
for r-l+1 > 0 {
lenAndOne := r - l + 2
bloom := 3
k := 1
for bloom <= lenAndOne/3 {
bloom *= 3
k++
}
m := (bloom - 1) / 2
mid := (l + r) / 2
rotate(nums, l+m, mid, mid+m)
cycles(nums, l-1, bloom, k)
l = l + bloom - 1
}
}
func cycles(nums []int, base int, bloom int, k int) {
for i, trigger := 0, 1; i < k; i, trigger = i+1, trigger*3 {
next := (2 * trigger) % bloom
cur := next
record := nums[next+base]
tmp := 0
nums[next+base] = nums[trigger+base]
for cur != trigger {
next = (2 * cur) % bloom
tmp = nums[next+base]
nums[next+base] = record
cur = next
record = tmp
}
}
}
func rotate(arr []int, l int, m int, r int) {
reverse(arr, l, m)
reverse(arr, m+1, r)
reverse(arr, l, r)
}
func reverse(arr []int, l int, r int) {
for l < r {
arr[l], arr[r] = arr[r], arr[l]
l++
r--
}
}
执行结果如下:
2021-11-05:摆动排序 II。给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。你可以假设所有输入数组都可以的更多相关文章
- Leetcode 324.摆动排序II
摆动排序II 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序. 示例 1: 输入: nums ...
- Java实现 LeetCode 324 摆动排序 II
324. 摆动排序 II 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]- 的顺序. 示例 1: 输入: n ...
- 2021.11.05 eleveni的水省选题的记录
2021.11.05 eleveni的水省选题的记录 因为eleveni比较菜,但是eleveni不想写绿题(总不能说是被绿题虐得不想写),eleveni决定继续水noip原题. --实际上菜菜的el ...
- [LeetCode] 324. Wiggle Sort II 摆动排序 II
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...
- 324. 摆动排序 II(三路划分算法)
题目: 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序. 示例 1: 输入: nums = [ ...
- LeetCode——324. 摆动排序 II
给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序. 示例 1: 输入: nums = [1, 5 ...
- 324 Wiggle Sort II 摆动排序 II
给定一个无序的数组nums,将它重新排列成nums[0] < nums[1] > nums[2] < nums[3]...的顺序.例子:(1) 给定nums = [1, 5, 1, ...
- [Leetcode] 第324题 摆动排序II
一.题目描述 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序. 示例 1: 输入: nums ...
- leetcode324 摆动排序II
1. 首先考虑排序后交替插入 首尾交替插入,这种方法对于有重复数字的数组不可行: class Solution { public: void wiggleSort(vector<int> ...
- [Swift]LeetCode324. 摆动排序 II | Wiggle Sort II
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...
随机推荐
- vue 缓存后台获取的token
代码 localStorage.setItem("token",res.data.data);// 用localStorage缓存token值
- Cmakelist如何添加自己的组件
在components文件夹下添加各组件的CMakeList,其中可以设置的变量如下: COMPONENT_SRCS:要编译进当前组件的源文件的路径,推荐使用此方法向构建系统中添加源文件.COMPON ...
- Android笔记--基础的连接数据库的操作
start.java package com.example.myapplication; import androidx.activity.result.ActivityResult; import ...
- 基于.Net开发的、支持多平台、多语言餐厅点餐系统
今天给大家推荐一套支持多平台.多语言版本的订单系统,适合餐厅.酒店等场景. 项目简介 这是基于.Net Framework开发的,支持手机.平板.PC等平台.多语言版本开源的点餐系统,非常适合餐厅.便 ...
- Golang数据结构
数据类型 不同类型的内存样式图 append,切片添加元素 清空切片的3种方法 清空切片的2种方法 查看变量类型 使用 fmt.Printf package main import "fmt ...
- Linux防火墙与端口操作命令
CentOS 7系统 目录 1. 防火墙操作命令 2. 端口操作命令 3. CentOS 7 下安装firewall 1. 防火墙操作命令 序号 作用 命令 1 查看防火墙状态 systemctl s ...
- 内核不中断前提下,Gaussdb(DWS)内存报错排查方法
摘要:本文主要讲解如何在内核保证操作不能中断采取的特殊处理,理论上用户执行的sql使用的内存(dynamic_used_memory) 是不会大范围的超过max_dynamic_memory的内存的 ...
- 【ACM算法竞赛日常训练】DAY5题解与分析【储物点的距离】【糖糖别胡说,我真的不是签到题目】| 前缀和 | 思维
DAY5共2题: 储物点的距离(前缀和) 糖糖别胡说,我真的不是签到题目(multiset,思维) 作者:Eriktse 简介:19岁,211计算机在读,现役ACM银牌选手力争以通俗易懂的方式讲解算法 ...
- vue中关于对象的监听与数组的监听
数组: 数组可监听到的方法:'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' 如果是根据索引改变值,需要使用vue.$set ...
- Ubuntu+uWSGI部署基于Django的API【鸿篇巨制,事无巨细】
背景 任务: 视频翻译项目需要在两个服务器上进行通信(国内&海外的阿里服务器). 因为python是主语言,选用了Django 来快速部署API. 注:Django中文文档:https://d ...