2023-04-16:给定一个长度为N的数组,值一定在0~N-1范围,且每个值不重复 比如,arr = [4, 2, 0, 3, 1] 0 1 2 3 4 把0想象成洞
2023-04-16:给定一个长度为N的数组,值一定在0~N-1范围,且每个值不重复
比如,arr = [4, 2, 0, 3, 1]
0 1 2 3 4
把0想象成洞,任何非0数字都可以来到这个洞里,然后在原本的位置留下洞
比如4这个数字,来到0所代表的洞里,那么数组变成 :
arr = [0, 2, 4, 3, 1]
也就是原来的洞被4填满,4走后留下了洞
任何数字只能搬家到洞里,并且走后留下洞
通过搬家的方式,想变成有序的,有序有两种形式
比如arr = [4, 2, 0, 3, 1],变成
[0, 1, 2, 3, 4]或者[1, 2, 3, 4, 0]都叫有序。
返回变成任何一种有序的情况都可以,最少的数字搬动次数。
来自谷歌。
答案2023-04-16:
解题步骤:
对于第一种有序情况,我们可以模拟交换排序的过程,算出需要交换的次数,具体实现见函数sortArray()。
对于第二种有序情况,我们可以先倒序遍历数组,找出每个数需要移动的最小距离,从而计算出需要移动的次数。
最后比较这两种情况下的最小搬动次数,返回较小值即可。
注意事项:
需要记录每个数是否被遍历过,以防止重复计算。
数字只能搬家到洞里,并且走后留下洞,因此在交换过程中需要记录其中一个数字所在的位置作为洞的位置。
golang代码如下:
package main
import "fmt"
func sortArray(nums []int) int {
// 长度n
// ans1 : 0 1 2 3 4 .... 这种样子,至少交换几次
// ans2 : 1 2 3 4 .... 0 这种样子,至少交换几次
// m : 每个环里有几个数
// next : 往下跳的位置
n := len(nums)
ans1, ans2 := 0, 0
touched := make([]bool, n)
// 0 1 2 3 4...
for i := 0; i < n; i++ {
if !touched[i] {
touched[i] = true
m := 1
next := nums[i]
for next != i {
m++
touched[next] = true
next = nums[next]
}
// m 当前环,有几个数
// 6
// 6
if m > 1 {
if i == 0 {
ans1 += m - 1
} else {
ans1 += m + 1
}
}
}
}
touched = make([]bool, n)
// 1 2 3 4 ... 0
// i == n-1
for i := n - 1; i >= 0; i-- {
if !touched[i] {
touched[i] = true
m := 1
// next
// 5
// i(8) -> 4
// 0
// i(8) -> n-1
next := nums[i]
if next == 0 {
next = n - 1
} else {
next--
}
for next != i {
m++
touched[next] = true
if nums[next] == 0 {
next = n - 1
} else if next > 0 {
next--
} else {
next = n - 1
}
}
if m > 1 {
if i == n-1 {
ans2 += m - 1
} else {
ans2 += m + 1
}
}
}
}
if ans1 < ans2 {
return ans1
}
return ans2
}
func main() {
nums := []int{4, 2, 0, 3, 1}
ans := sortArray(nums)
fmt.Println(ans) // 输出 3
}
rust代码如下:
fn sort_array(nums: &[i32]) -> i32 {
let n = nums.len() as i32;
let mut ans1 = 0;
let mut ans2 = 0;
let mut touched = vec![false; n as usize];
for i in 0..n {
if !touched[i as usize] {
touched[i as usize] = true;
let mut m = 1;
let mut next = nums[i as usize];
while next != i {
m += 1;
touched[next as usize] = true;
next = nums[next as usize];
}
if m > 1 {
if i == 0 {
ans1 += m - 1;
} else {
ans1 += m + 1;
}
}
}
}
touched = vec![false; n as usize];
for i in (0..n).rev() {
if !touched[i as usize] {
touched[i as usize] = true;
let mut m = 1;
let mut next = if nums[i as usize] == 0 {
n - 1
} else {
nums[i as usize] - 1
};
while next != i {
m += 1;
touched[next as usize] = true;
next = if nums[next as usize] == 0 {
n - 1
} else {
nums[next as usize] - 1
};
}
if m > 1 {
if i == n - 1 {
ans2 += m - 1;
} else {
ans2 += m + 1;
}
}
}
}
ans1.min(ans2)
}
fn main() {
let nums = vec![4, 2, 0, 3, 1];
let ans = sort_array(&nums);
println!("{}", ans); // 输出 3
}
2023-04-16:给定一个长度为N的数组,值一定在0~N-1范围,且每个值不重复 比如,arr = [4, 2, 0, 3, 1] 0 1 2 3 4 把0想象成洞的更多相关文章
- 面试题:给定一个长度为N的数组,其中每个元素的取值范围都是1到N。判断数组中是否有重复的数字
题目:给定一个长度为N的数组,其中每个元素的取值范围都是1到N.判断数组中是否有重复的数字.(原数组不必保留) 方法1.对数组进行排序(快速,堆),然后比较相邻的元素是否相同.时间复杂度为O(nlog ...
- 给定一个长度为N的数组,找出出现次数大于n/2,n/3的数,要求时间复杂度O(n),空间复杂度O(1)
先讨论出现次数大于n/2的数字,如果这样的数字存在,那么这个数出现的次数大于其他数出现的次数的总和. 在数组A中,我们定义两个数据集合a1,a2.a1为出现次数大于n/2的数的集合,a2为其余数组成的 ...
- 给定数组a[1,2,3],用a里面的元素来生成一个长度为5的数组,打印出其排列组合
给定数组a[1,2,3],用a里面的元素来生成一个长度为5的数组,打印出其排列组合 ruby代码: def all_possible_arr arr, length = 5 ret = [] leng ...
- 用最小的空间复杂度找出一个长度为n的数组且数据中的元素是[0,n-1]中任一个重复的数据。
用最小的空间复杂度找出一个长度为n的数组且数据中的元素是[0,n-1]中任一个重复的数据. 比如:[1, 2, 3, 3, 2, 2, 6, 7, 8, 9] 中 2 or 3 分析:这道题目,实现比 ...
- 不用循环,、es6创建一个长度为100的数组
问题描述:在不使用循环的条件下,如何创建一个长度为100的数组,并且数组的每一个元素是该元素的下标? 结果为: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1 ...
- 前端面试题:不使用loop循环,创建一个长度为100的数组,并且每个元素的值等于它的下标,,怎么实现好?
昨天,看这道题,脑子锈住了,就是没有思路,没看明白是什么意思?⊙﹏⊙|∣今天早上起床,想到需要思考一下这个问题. 当然,我没想明白为什么要这样做?(创建一个长度为100的数组,并且每个元素的值等于它的 ...
- java—数组乘积输入: 一个长度为n的整数数组input 输出: 一个长度为n的数组result,满足result[i] = input数组中,除了input[i] 之外的所有数的乘积,不用考虑溢出例如 input {2, 3, 4, 5} output: {60, 40, 30, 24}
/** * 小米关于小米笔试题 数组乘积输入: 一个长度为n的整数数组input 输出: 一个长度为n的数组result,满足result[i] = * input数组中,除了input[i] 之外的 ...
- 创建一个长度是5的数组,并填充随机数。使用for循环或者while循环,对这个数组实现反转效果
package day01; import java.util.Random; /** * 首先创建一个长度是5的数组,并填充随机数.使用for循环或者while循环,对这个数组实现反转效果 * @a ...
- 一个简单的算法,定义一个长度为n的数组,随机顺序存储1至n的的全部正整数,不重复。
前些天看到.net笔试习题集上的一道小题,要求将1至100内的正整数随机填充到一个长度为100的数组,求一个简单的算法. 今天有空写了一下.代码如下,注释比较详细: using System; usi ...
- 《疯狂Java:突破程序员基本功的16课》读书笔记-第一章 数组与内存控制
很早以前就听过李刚老师的疯狂java系列很不错,所以最近找一本拿来拜读,再此做下读书笔记,促进更好的消化. 使用Java数组之前必须先对数组对象进行初始化.当数组的所有元素都被分配了合适的内存空间,并 ...
随机推荐
- mysql根据一个表更新另外一个表
-- 语法:update table_1 t1,table_2 t2 set t1.column = t2.column where t1.id = t2.pid; UPDATE house_test ...
- 随笔:for in 和 for of的区别
百度前端面试题:for in 和 for of的区别详解以及为for in的输出顺序 - 知乎 以该页面为例,我稍微总结一点东西: 在这⾥我们把对象中的数字属性称为 「排序属性」,在V8中被称为 el ...
- JDMasking v0.1.0-beta 发布
JDMasking 全称是jdbc data masking,是一款零代码修改.无重启.基于JDBC的动态数据脱敏软件. JDMasking 主要对实现jdbc的驱动进行字节码的增强,支持对运行中的程 ...
- 服务器中VirtualBox子网访问
本人常用的虚拟机软件是VirtualBox,由于笔记本性能,磁盘存储大下限制,以及VirtualBox客户机无法在多个设备间直接方便的使用等原因,我把几个虚拟的系统全部移动到便携式服务器中. 移动之后 ...
- Maven 切换JDK版本
欢迎访问我的个人博客:xie-kang.com 查看Maven安装目录的conf目录可以看到有 settings.xml\toolchains.xml文件.settings.xml主要是设置切换Mav ...
- excel里面嵌入一个表格
excel里怎么嵌入表格 excel是我们工作中经常会用的软件,有时两表格想放在一起比较,但是行高列宽调起来顾此失彼,so: 软件版本:Microsoft Office Excel 2010 操作系统 ...
- SpringBoot——常用配置
application.yml配置信息 spring: profiles: active: dev application: name: jwt-token-security # Jackson 配置 ...
- meterpreter的使用
meterpreter是metasploit中的一个杀手锏,通常在漏洞利用成功后,会返回给攻击者一个攻击通道,其中有很多自动化操作 场景布置 生成木马 首先,我们使用metasploit中的另一个后门 ...
- 继续Vue的探索
接上集 上次到了想要利用Vue实现隔行变色的请求,但是由于使用的代码过于"高级"导致无法识别,这就需要利用webpack来解决它! webpack的基本使用 1.首先,在项目中安装 ...
- 使用MyBatis时需要注意到的事情------执行添加、修改和删除操作时,一定要记得提交事务
今天在重写添加操作代码时,发现自己写的代码没有任何报错,使用断点进行查询,发现一切正常,但是注册使用的数据就是无法添加到数据库里面 然后就去之前看过的视频里面去找错误,就发现这样一个小细节: 在视频里 ...