c语言实现小米面试题,知乎小米变相约瑟夫环面试题微软解法rust代码

原题: 一副从1到n的牌,每次从牌堆顶取一张放桌子上,再取一张放牌堆底,直到手机没牌,最后桌子上的牌是从1到n有序,设计程序,输入n,输出牌堆的顺序数组 。

微软君给的算法: 取一个1~n的数组,这里为了说明取n=5。按照题目中的规则变换,得到数组:[1 3 5 4 2],将该数组下标与值互换得到[1 5 2 4 3],即为答案。解释:[1 3 5 4 2]的意义是,经过变换,原数组中3号位置的数字现在2号槽,原数组中5号位置的数字现在3号槽... 现在已知变换后的槽存放的是1~n,故只需将下标与值互换即可得到待求数组。

// 计算约瑟夫变相环

/*

rust代码 变相约瑟夫环。知乎上一个小米面试题的微软解法(细节去知乎找找看)

原题: 一副从1到n的牌,每次从牌堆顶取一张放桌子上,再取一张放牌堆底,直到手机没牌,最后桌子上的牌是从1到n有序,设计程序,输入n,输出牌堆的顺序数组 。

微软君给的算法: 取一个1~n的数组,这里为了说明取n=5。按照题目中的规则变换,得到数组:[1 3 5 4 2],将该数组下标与值互换得到[1 5 2 4 3],即为答案。解释:[1 3 5 4 2]的意义是,经过变换,原数组中3号位置的数字现在2号槽,原数组中5号位置的数字现在3号槽... 现在已知变换后的槽存放的是1~n,故只需将下标与值互换即可得到待求数组。

*/

// joseph2

// 构成一个Vec队列

fn make_array(num: i32) -> Vec{

let mut v = Vec::new();

for element in 1..(num+1) {

v.push(element);

}

return v;

}

// 根据原始数据构成一个中间Vec

fn count_mid_array(array: &mut Vec) -> Vec{

let mut v = Vec::new();

while array.len() > 1{ // 长度大1

let t1 = array.remove(0); // 移除首个

v.push(t1); // 插入中间组

let t2 = array.remove(0); // 再移除首个

array.push(t2); // 插入到原组结尾

}

v.push(array[0]); // 插入剩余的最后一个

return v;

}

// 转换结果数组

fn trans_array(n: i32, new_array: Vec) -> Vec{

let mut fin_array = Vec::new();

for i in 1..(n + 1) {

for (pos, e) in new_array.iter().enumerate(){ // 带索引

if i == *e{ // 这里对比值要*解引用

fin_array.push((pos+1) as i32); // 插入,pos是usize要转换一下

}

}

}

return fin_array

}

// 测试程序入口

pub fn joseph2_test(){

let n = 1210;

let mut v = make_array(n);

println!("原始数组 {:?}", v);

let v2 = count_mid_array(&mut v);

println!("计算中间组 {:?}", v2);

let fin_v = trans_array(n, v2);

println!("最终结果: {:?}", fin_v);

}

fn main(){

joseph2_test();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值