-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 126 题:扑克牌问题 #245
Comments
不知道对不对,还请大神指教纠错。 |
|
|
先放一波验证方法 勿喷,等会扔出来我解题方法(上面大佬们写的解题方法比我的强得多)
|
这里从屁股拿出来再塞回屁股啊 ㄟ( ▔, ▔ )ㄏ |
第一印象搞出来的烂摊子。。。 自己都感觉很烂了。。当个记录吧 希望半年后不会这么烂了
|
|
//[7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13] |
|
看下来唯一一个对的,大家都是在原数组上操作pop和shift了。不过最后答案应该再反过来表示。 |
@nssol-fengzhichao 啥意思 |
|
@HCLQ 这位道友,我倒觉得做法是对的 |
|
建议还是参考楼上的大佬们比较好,我只想写一下自己的想法,很废时间,不是很建议。 处理的话,可能是个取巧的方法,刚刚开始理解错了题意 |
|
这句是说放在新牌堆的底,还是旧牌堆的底? |
/**
* 逆向:即从桌牌到手牌
* @param {*} 桌牌序列 arr
*/
function recover(arr) {
const res = []
while (arr.length > 0) {
if (res.length) {
res.push(res.shift())
}
const item = arr.pop()
res.push(item)
}
return res
}
/**
* 正向:即从手牌到桌牌(用于检验结果)
* @param {*} 手牌序列arr
*/
function generate(arr) {
const res = []
while (arr.length > 0) {
const item = arr.pop()
res.push(item)
if (arr.length) {
arr.unshift(arr.pop())
}
}
return res
}
recover([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) // [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]
generate([7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] |
留个小小的见解
/**
/**
/**
let card = { console.log(card) // { old: [ 1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7 ], new: [] }` |
我还是不理解这个 大佬 讲解一下为什么 |
是的,这个很关键。我猜测大概率是放到旧牌堆的底。 |
这个答案的顺序: 牌顶是 数组的第一项,按照出题人的套路: 牌顶是数组最后一项, |
每次将桌上牌的最上面一张放到原牌堆顶,然后将原牌堆底的牌放到原牌堆顶 |
精髓 |
我就说怎么我做的和大家都不同,我理解的题目是从原先的牌堆a1中取出顶部一张到a2中,然后a1顶部取一张牌放在a1的地步,再从a1中取一张放a2中,如此循环。。。给了差评的我去撤销掉。。。大概是我理解错了吧。。。 |
|
function sortPuke(arr) { |
// 复原
function recover(arr) {
return arr.reduceRight((res, cur) => {
if (res.length) {
res.push(res.shift());
}
res.push(cur);
return res;
}, []);
}
const res = recover([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
console.log(res);
// 打乱,验证使用
function shuffle(arr, result = [], joinRes = true) {
return arr.reduceRight((res, cur, index) => {
res[res.joinRes ? 'result' : 'now'][res.joinRes ? 'push' : 'unshift'](cur);
res.joinRes = !res.joinRes;
if (!index && res.now.length) {
shuffle(res.now, res.result, res.joinRes);
}
return res;
}, { result, now: [], joinRes }).result;
}
console.log(shuffle(res)); 点击展开查看打乱过程
|
需要再翻转一下 |
function paixu(){ |
|
先写出来正序的方法再改成倒叙,解决起来就会简单一些!
|
function reverse(arr) {
let i = 1
let out = []
while (arr.length) {
if (i % 2) {
out.push(arr.pop())
} else {
out.push(out.shift())
}
i++
}
return out
} |
|
|
/**
有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复;
最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶);
问:原来那堆牌的顺序,用函数实现。
*/
const res = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
/**
=> 231
32
3
<= 123
=> 4231
342
43
4
<= 1234
=> 34251
5342
453
54
5
<= 12345
*/
function sort(data) {
const arr = []
let i = 1
while (data.length) {
const top = data.pop()
if (i % 2 === 0) {
data.unshift(top)
} else {
arr.push(top)
}
i++
}
return arr
}
function sortReverse(data) {
const arr = []
let len = data.length
while (len) {
const top = data.pop()
if (arr.length > 1) {
const last = arr.shift()
arr.push(last)
}
arr.push(top)
len--
}
return arr
}
const origin = sortReverse([...res])
console.log(origin)
const result = sort(origin)
console.log(result)
console.log(JSON.stringify(result) === JSON.stringify(res)) |
有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复;
最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶);
问:原来那堆牌的顺序,用函数实现。
function reverse(arr) {
let i = 1
let out = []
while (arr.length) {
if (i % 2) {
out.unshift(arr.pop())
} else {
out.unshift(out.pop())
}
i++
}
return out
}
有一堆扑克牌,将牌堆第一张放到桌子上,再将桌子上牌堆的最后一张放到牌顶,如此往复;
最后桌子上的牌顺序为: (牌底) 1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7 (牌顶);
问:原来那堆牌的顺序,用函数实现。
function poke(arr) {
let i = 1
let out = []
while (arr.length) {
if (i % 2) {
out.push(arr.shift())
} else {
arr.push(arr.shift())
}
i++
}
return out
} 这样理解是不是会容易很多? |
function sortPoke () {
const right = [1,2,3,4,5,6,7,8,9,10,11,12,13]
const left = right.splice(0, (right.length | 0) / 2)
var r = []
while (left.length || right.length) {
const r1 = right.shift()
const r2 = left.pop()
if (r1) r.push(r1)
if (r2) r.push(r2)
}
console.log(r)
} |
function restore(poke) {
let arr = [];
while (poke.length) {
arr.push(poke.pop());
arr.push(arr.shift());
}
// 最后回滚多走的一步
arr.unshift(arr.pop());
return arr;
} |
function handle(oldArr) {
var newArr = [oldArr[oldArr.length-1]]
var flag = true
for(let i = oldArr.length-2;i>=0;i--){
var a = newArr.pop()
newArr.unshift(a)
newArr.unshift(oldArr[i])
}
return newArr
}
let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13]
console.log(handle(arr)) |
从牌桌拿回的时候,先要把最后一张置顶,也就是
|
写一下自己的理解 // arr : A(牌堆): 底 【1, 。。。。, 13】 顶
// res: B (手里): 底 【】 顶
// 原操作:B顶 => A顶 B顶 => B底 (如果B有多张)
// 逆向操作:B底 => B顶 (如果B有多张) A顶 => B顶
const reverse = arr => {
const res = [];
while (arr.length > 0) {
if (res.length) {
res.push(res.shift());
}
const item = arr.pop();
res.push(item);
}
return res;
};
// 输出 手里牌
// 底 [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ] 顶 |
执行一个逆向操作就好了,从桌上牌顶拿一张放到手中牌顶,再把手里的牌底一张移到牌顶,如此循环 function resumePoke(arr) {
let pre = []
let len = arr.length
while (arr.length) {
pre.push(arr.pop())
// 手里的牌大于 1 张才移动,桌上牌拿空时则不移动
if (pre.length > 1 && pre.length < len) {
pre.push(pre.shift())
}
}
console.log('pre', pre)
return pre
}
resumePoke([1,2,3,4,5,6,7,8,9,10,11,12,13])
// pre (13) [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1] |
var r = []; |
function reduction(arr) {
let res = []
while (arr.length) {
if (res.length) {
res.push(res.shift())
}
res.push(arr.pop())
}
return res
}
reduction([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
// [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1] |
|
大神的思路总是这么清晰,我这个菜鸡只能学习一波。不过倒是发现了一个可优化的点:数组的 shift 和 unshift 操作复杂度为线性,面试时有意将其优化掉应该会是个亮点。 /**
* 逆向:即从桌牌到手牌
* @param {*} 桌牌序列 arr
*/
function recover(arr) {
const res = []
let i = 0
while (arr.length > 0) {
if (res.length) {
res.push(res[i++])
}
const item = arr.pop()
res.push(item)
}
return res.slice(i)
}
/**
* 正向:即从手牌到桌牌(用于检验结果)
* @param {*} 手牌序列arr
*/
function generate(arr) {
const res = [], l = arr.length
let i = 0
arr = arr.reverse()
while (res.length < l) {
const item = arr[i++]
res.push(item)
if (res.length < l) {
arr.push(arr[i++])
}
}
return res
}
console.log(recover([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])) // [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]
console.log(generate([7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1])) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] |
function poker(array = []) {
let origin = [];
while (array.length !== 0) {
if (origin.length > 0) {
origin.push(origin.shift());
}
origin.push(array.pop());
}
return origin;
}
console.log(poker([1,2,3,4,5,6,7,8,9,10,11,12,13]));
//[7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1] |
function reverses(data = []) {
let result = [];
while (data.length) {
let prev = result.shift();
if (prev) {
result.push(prev);
}
result.push(data.pop());
}
return result;
}
reverses([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
// [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1] |
看上的答案心都凉了,终于看到了一样的 |
const data = [1,2,3,4,5,6,7,8,9,10,11,12,13]
// 将操作倒放即可
// 原来是从牌顶上拿一张牌放到桌子上,再将牌顶的牌放到牌底
// 倒放:将牌底的牌放到牌顶,再从桌子上拿一张牌放到牌顶
function reverse(data) {
const result = []
while (data.length) {
// 由于一开始 result 没有牌,不能执行 “将牌底的牌放到牌底” 这一步操作,所以跳过
if (result.length) {
result.unshift(result.pop())
}
result.unshift(data.pop())
}
return result
}
console.log(reverse(data)) // [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7] |
|
你好,邮件已收到,我现在未上线,一会儿回复你。
|
|
你好,邮件已收到,我现在未上线,一会儿回复你。
|
|
你好,邮件已收到,我现在未上线,一会儿回复你。
|
有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复;
最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶);
问:原来那堆牌的顺序,用函数实现。
The text was updated successfully, but these errors were encountered: