第 126 题:扑克牌问题
有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复,最后桌子上的牌顺序为: 牌底 1,2,3,4,5,6,7,8,9,10,11,12,13 牌顶;
问:原来那堆牌的顺序,用函数实现。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复,最后桌子上的牌顺序为: 牌底 1,2,3,4,5,6,7,8,9,10,11,12,13 牌顶;
问:原来那堆牌的顺序,用函数实现。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(57)
我还是不理解这个 大佬 讲解一下为什么
是的,这个很关键。我猜测大概率是放到旧牌堆的底。
这个答案的顺序: 牌顶是 数组的第一项,按照出题人的套路: 牌顶是数组最后一项,
所以最好是答案再反过来
每次将桌上牌的最上面一张放到原牌堆顶,然后将原牌堆底的牌放到原牌堆顶
精髓
我就说怎么我做的和大家都不同,我理解的题目是从原先的牌堆a1中取出顶部一张到a2中,然后a1顶部取一张牌放在a1的地步,再从a1中取一张放a2中,如此循环。。。给了差评的我去撤销掉。。。大概是我理解错了吧。。。
function sortPuke(arr) {
let keyList = [];//arr对应的key
let alenList = [];
let result = [];//最终结果
let spot = true;
if (arr.length === 1) {
return arr
}
if (arr.length > 1) {
for (let index = 0; index < arr.length; index++) {
alenList.push(index)
}
while (alenList.length) {
if (alenList.length === 1) {
keyList.push(alenList.shift())
}
if (spot && alenList.length > 1) {
keyList.push(alenList.shift())
}
if (!spot && alenList.length > 1) {
alenList.push(alenList.shift())
}
spot = !spot
}
}
for (let j = 0; j < arr.length; j++) {
result[keyList[j]] = arr[j]
}
return result;
}
console.log(sortPuke([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]));
//[ 1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7 ]
点击展开查看打乱过程
需要再翻转一下
解题思路:
桌上初始牌堆记为A1,排完后的牌堆记为A2。
(正向过程)A1顶部第一张->A2顶部,剩下的A1顶部第一张放到A1底部,此为一轮;...重复过程直到A1全部放到A2中,最后一轮过程只有A1顶部第一张->A2顶部这一个步骤。
(反向过程)1.将A2顶部第一张还回A1;2.执行正向过程每一轮的逆过程即可(A1底部第一张->A1顶部,A2顶部第一张->A1顶部),直到A2中没有牌为止。
看我的
后面发现我的题目与原题不同,下次再来写原题的答案~~
好了,原题答案也来了
这里使用的是:1是牌顶,13是牌顶的初始牌,方向不同结果也会不同
function paixu(){
let arrstart = [1,2,3,4,5,6,7,8,9,10,11,12,13];
let benlai = [];
let item;
let ben;
// 牌底---》牌顶
// 先把第一张拿出来
// 把剩下的第一个放到最后
// 循环往复
// 换算成代码
// [>>>>>>>>>>>>>] 右边是牌顶,牌顶远离桌面的
// item = benlai.pop() // 把牌顶(尾,用pop)那个拿出来就是第一张拿出来,
// arrstart.push(item) // 把这一个放到Arrsatrt的牌底(头,unshift)
// b = benlai.pop() // 把牌顶(尾用pop)拿出来,
// benlai.unshift(b) // 把这个值,放到牌底(头用unshift)
while(arrstart.length>1){
item = arrstart.pop();
console.log(item)
benlai.push(item);
ben = benlai.shift();
benlai.push(ben);
}
item = arrstart.pop();
benlai.push(item);
console.log(benlai.reverse())
}
paixu();
来自宝宝熊&&熊熊宝
先写出来正序的方法再改成倒叙,解决起来就会简单一些!
这样理解是不是会容易很多?
从牌桌拿回的时候,先要把最后一张置顶,也就是
result.unshift(result.pop())
。之后就是基本操作
写一下自己的理解
执行一个逆向操作就好了,从桌上牌顶拿一张放到手中牌顶,再把手里的牌底一张移到牌顶,如此循环
var r = [];
const change = num =>{let t = r.pop();r.unshift(num,t);}
[1,2,3,4,5,6,7,8,9,10,11,12,13].reverse().map(v=>{change(v);})
弄了一个图
大神的思路总是这么清晰,我这个菜鸡只能学习一波。不过倒是发现了一个可优化的点:数组的 shift 和 unshift 操作复杂度为线性,面试时有意将其优化掉应该会是个亮点。
看上的答案心都凉了,终于看到了一样的
留个小小的见解
`/**
*/
function pipe(...fns) {
return function(x) {
return fns.reduce(function(arg,fn) {
return fn(arg)
},x)
}
}
/**
*/
function removeNewLastToOldFirst(card) {
card.old = [card.new.pop(),...card.old];
return card;
}
/**
*/
function reverseLastToFisrt(card) {
let last = card.old.pop();
if(last) {
card.old = [last,...card.old];
}
return card;
}
/**
*/
function cardSort(card) {
if(card.new.length > 0) {
pipe(reverseLastToFisrt,removeNewLastToOldFirst)(card)
cardSort(card)
} else {
return;
}
}
let card = {
old: [],
new: [1,2,3,4,5,6,7,8,9,10,11,12,13]
}
cardSort(card)
console.log(card) // { old: [ 1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7 ], new: [] }`
这句是说放在新牌堆的底,还是旧牌堆的底?
建议还是参考楼上的大佬们比较好,我只想写一下自己的想法,很废时间,不是很建议。
开始好像理解错了题意,最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶);
桌上的牌顺序是从下往上 1-n , 我推的是 从上往下 1-n ,推反了
(桌上的牌相当于一个栈,但没关系后面处理一下,把13当成了1,主要是反着推不出来 愁呀)
用数学举例,
结束 =》开始
1 =》 1
1 2 =》2 1
1 2 3 =》3 1 2
1 2 3 4 =》 4 2 3 1
1 2 3 4 5 =》 5 1 4 2 3
1 2 3 4 5 6 =》 6 3 5 1 4 2
1 2 3 4 5 6 7 =》 7 2 6 3 5 1 4
1 2 3 4 5 6 7 8 =》 8 4 7 2 6 3 5 1
1 2 3 4 5 6 7 8 9 =》 9 1 8 4 7 2 6 3 5
1 2 3 4 5 6 7 8 9 10 =》 10 5 9 1 8 4 7 2 6 3
1 2 3 4 5 6 7 8 9 10 11 =》 11 3 10 5 9 1 8 4 7 2 6
1 2 3 4 5 6 7 8 9 10 11 12 =》 12 6 11 3 10 5 9 1 8 4 7 2
1 2 3 4 5 6 7 8 9 10 11 12 13 =》 13 2 12 6 11 3 10 5 9 1 8 4 7
规律的话 1 2 3 4 5 =》5 1 4 2 3 进行循环得到 4 2 3 1
所以可以用前面的推出后面的
处理的话,可能是个取巧的方法,刚刚开始理解错了题意
(每个数+自己的结果 = 14),比如,把13当成1 即 13+1 = 14
[1 12 2 8 3 11 4 9 5 13 6 10 7]
@HCLQ 这位道友,我倒觉得做法是对的
@nssol-fengzhichao 啥意思
看下来唯一一个对的,大家都是在原数组上操作pop和shift了。不过最后答案应该再反过来表示。
//[7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]
第一印象搞出来的烂摊子。。。 自己都感觉很烂了。。
当个记录吧 希望半年后不会这么烂了
这里从屁股拿出来再塞回屁股啊 ㄟ( ▔, ▔ )ㄏ
先放一波验证方法 勿喷,等会扔出来我解题方法(上面大佬们写的解题方法比我的强得多)
(牌底)[13, 1, 12, 2, 11, 3, 10, 4, 9, 5, 8, 6, 7](牌顶)
不知道对不对,还请大神指教纠错。