Daily-Interview-Question
Daily-Interview-Question copied to clipboard
第 126 题:扑克牌问题
有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复;
最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶);
问:原来那堆牌的顺序,用函数实现。
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
let _arr = []
function sortPoke() {
while (arr.length > 0) {
// 选择抽取哪张牌
if (arr.length % 2 == 1) {
_arr.push(arr.pop())
} else {
_arr.push(arr.shift())
}
}
return _arr.reverse()
}
console.log(sortPoke())
// [7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]
不知道对不对,还请大神指教纠错。
var list = [1,2,3,4,5,6,7,8,9,10,11,12,13];
function fn(list){
let curIndex = parseInt((list.length - 1) / 2);
let cur = list.splice(curIndex, 1);
if(list.length === 0) return cur;
return [...fn(list), cur[0]];
}
fn(list);
(牌底)[13, 1, 12, 2, 11, 3, 10, 4, 9, 5, 8, 6, 7](牌顶)
const reverseResult = [];
const reverseSort = arr => {
console.log("begin: ", arr, reverseResult);
if (reverseResult.length) {
reverseResult.unshift(reverseResult.pop());
}
if (arr.length) {
reverseResult.unshift(arr.pop());
console.log("end: ", arr, reverseResult);
if (arr.length) {
reverseSort(arr);
}
}
};
先放一波验证方法 勿喷,等会扔出来我解题方法(上面大佬们写的解题方法比我的强得多)
function handle(arr = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
]) {
const result = [];
for (let i = 0; i < arr.length; i++) {
if (i % 2) {
result.push({ value: arr[i] })
} else {
result.unshift({ value: arr[i] })
}
}
result.unshift({ value: "牌顶" });
result.push({ value: "牌底" });
console.log(result);
}
handle([7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]);
/* [ { value: '牌顶' },
{ value: 13 },
{ value: 12 },
{ value: 11 },
{ value: 10 },
{ value: 9 },
{ value: 8 },
{ value: 7 },
{ value: 6 },
{ value: 5 },
{ value: 4 },
{ value: 3 },
{ value: 2 },
{ value: 1 },
{ value: '牌底' } ]*/
if (arr.length % 2 == 1) { _arr.push(arr.pop())
这里从屁股拿出来再塞回屁股啊 ㄟ( ▔, ▔ )ㄏ
第一印象搞出来的烂摊子。。。 自己都感觉很烂了。。
当个记录吧 希望半年后不会这么烂了
// 牌底 -> 牌顶
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
const arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
function handle(sortGroup) {
const original = [];
const len = sortGroup.length;
const lastindex = len - 1;
// 中间值
let middleIndex = Math.floor(len / 2) - 1;
// 如果是单数 从牌顶开始
// 如果是双数 从牌底开始
if (len % 2) {
sortGroup = sortGroup.reverse();
middleIndex ++;
}
for (let i = 0; i < len; i++) {
if (i > middleIndex) {
break;
}
original.unshift(sortGroup[i])
if (len % 2 && i == middleIndex) {
continue;
}
original.unshift(sortGroup[lastindex - i])
}
return original;
}
const result = handle(arr);
const result2 = handle(arr2);
// [ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13 ]
console.log(result);
// [ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1 ]
console.log(result2);
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 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
}
reverse([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]
var origin = [],top_half;
var res = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13].reverse();
top_half = res.splice(0,Math.floor((res.length-1)/2) + 1).reverse();
for (let i of top_half.keys()){
origin.push(top_half[i]);
res[i] && origin.push(res[i]);
}
console.log(origin);
//[7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
function recovery(array) {
const length = array.length;
let newArray = [];
for (let i = 0; i < length; i++) {
if (i % 2 == 0) {
newArray.push(array.pop())
} else {
newArray.push(array.shift())
}
}
return newArray;
};
recovery(arr);
// [ 13, 1, 12, 2, 11, 3, 10, 4, 9, 5, 8, 6, 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 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 } reverse([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]
看下来唯一一个对的,大家都是在原数组上操作pop和shift了。不过最后答案应该再反过来表示。
@nssol-fengzhichao 啥意思
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
function sort(arr) {
let pre = []
while (arr.length > 1) {
pre.push(arr.pop())
pre.push(pre.shift())
}
pre.push(arr.pop())
console.log(pre)
}
sort(arr)
// [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]
@HCLQ 这位道友,我倒觉得做法是对的
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
let num = Math.ceil(arr.length/2);
//判断奇偶性
let flag = arr.length%2 === 0?true:false;
let res = [];
for(let i = 0;i<num;i++){
if(flag){
res.unshift(arr[i]);
res.unshift(arr[arr.length-1-i])
}else{
res.unshift(arr[arr.length-1-i])
if(i < num-1){
res.unshift(arr[i]);
}
}
}
//结果是牌顶到排底
console.log(res)
//结果 [7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]
建议还是参考楼上的大佬们比较好,我只想写一下自己的想法,很废时间,不是很建议。 开始好像理解错了题意,最后桌子上的牌顺序为: (牌底) 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]
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
function reduction(arr) {
let newArr = [...arr],res = []
while (newArr.length) res.push(!(newArr.length % 2) ? newArr.shift() : newArr.pop())
return res.concat(newArr).reverse()
}
let res = reduction(arr)
console.log(res)
再将接下来的牌堆的第一张放到牌底
这句是说放在新牌堆的底,还是旧牌堆的底?
/**
* 逆向:即从桌牌到手牌
* @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]
留个小小的见解 `/**
- description: 管道函数执行
- @param {Function} fns 执行函数数组 */ function pipe(...fns) { return function(x) { return fns.reduce(function(arg,fn) { return fn(arg) },x) } }
/**
- description: 新卡组最后一张放到旧卡组第一张
- @param {Object} card */ function removeNewLastToOldFirst(card) { card.old = [card.new.pop(),...card.old]; return card; }
/**
- description: 旧卡组最后一张放到旧卡组第一张
- @param {Object} card */ function reverseLastToFisrt(card) { let last = card.old.pop(); if(last) { card.old = [last,...card.old]; } return card; }
/**
- description: 卡片排序
- @param {Object} 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: [] }`
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] function sort(arr) { let pre = [] while (arr.length > 1) { pre.push(arr.pop()) pre.push(pre.shift()) } pre.push(arr.pop()) console.log(pre) } sort(arr) // [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]
我还是不理解这个 大佬 讲解一下为什么
再将接下来的牌堆的第一张放到牌底
这句是说放在新牌堆的底,还是旧牌堆的底?
是的,这个很关键。我猜测大概率是放到旧牌堆的底。
@nssol-fengzhichao 啥意思
这个答案的顺序: 牌顶是 数组的第一项,按照出题人的套路: 牌顶是数组最后一项, 所以最好是答案再反过来
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] function sort(arr) { let pre = [] while (arr.length > 1) { pre.push(arr.pop()) pre.push(pre.shift()) } pre.push(arr.pop()) console.log(pre) } sort(arr) // [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]
我还是不理解这个 大佬 讲解一下为什么
每次将桌上牌的最上面一张放到原牌堆顶,然后将原牌堆底的牌放到原牌堆顶
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] function sort(arr) { let pre = [] while (arr.length > 1) { pre.push(arr.pop()) pre.push(pre.shift()) } pre.push(arr.pop()) console.log(pre) } sort(arr) // [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]
精髓
我就说怎么我做的和大家都不同,我理解的题目是从原先的牌堆a1中取出顶部一张到a2中,然后a1顶部取一张牌放在a1的地步,再从a1中取一张放a2中,如此循环。。。给了差评的我去撤销掉。。。大概是我理解错了吧。。。
let tmp = [1,2,3,4,5,6,7,8,9,10,11,12,13];
let result = [];
let action = 'pop'
while(tmp.length != 0){
let item = tmp[action]()
if(action == 'pop'){
action = 'shift'
}else{
action = 'pop'
}
result.push(item);
}
console.log(result); //打印出最后的牌顺序
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 ]
// 复原
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));
点击展开查看打乱过程
结果: []
手上: 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1
1
12, 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2
1,2
8, 12, 7, 10, 6, 13, 5, 9, 4, 11, 3
1,2,3
11, 8, 12, 7, 10, 6, 13, 5, 9, 4
1,2,3
11, 8, 12, 7, 10, 6, 13, 5, 9, 4
1,2,3,4
9,11, 8, 12, 7, 10, 6, 13, 5
1,2,3,4,5
13,9,11, 8, 12, 7, 10, 6
1,2,3,4,5,6
10,13,9,11, 8, 12, 7
1,2,3,4,5,6,7
12, 10,13,9,11,8
1,2,3,4,5,6,7,8
11,12,10,13,9
1,2,3,4,5,6,7,8,9
13,11,12, 10
1,2,3,4,5,6,7,8,9,10
12,13,11
1,2,3,4,5,6,7,8,9,10,11
13, 12
1,2,3,4,5,6,7,8,9,10,11, 12
13
结果: 1,2,3,4,5,6,7,8,9,10,11, 12,13
手上: []
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] function sort(arr) { let pre = [] while (arr.length > 1) { pre.push(arr.pop()) pre.push(pre.shift()) } pre.push(arr.pop()) console.log(pre) } sort(arr) // [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]
需要再翻转一下
poker (pokerArray) { let res = [] while (pokerArray.length > 1) { res.push(pokerArray.shift()) res.push(pokerArray.pop()) } if (pokerArray.length === 1) { res.push(pokerArray[0]) } console.log(res) } anthoerPoker (pokerArray) { let res = [] while (pokerArray.length > 0) { if (res.length > 0) { res.push(res.shift()) } res.push(pokerArray.pop()) } console.log(res) } // 牌底放到桌上 // 牌底[1, 13, 2, 12, 3, 11, 4, 10, 5, 9, 6, 8, 7]牌顶 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]牌顶 anthoerPoker([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
const result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
const arr = [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7];
function reverse(result) {
const ans = [];
result.reverse();
for (let item of result) {
if (ans.length) {
const tem = ans.pop();
ans.unshift(tem);
}
ans.unshift(item);
}
return ans;
}
console.log(reverse(result));
function sort(arr) {
const ans = [];
while (arr.length) {
ans.push(arr.shift());
if (!arr.length) break;
const tem = arr.shift();
arr.push(tem);
}
return ans;
}
console.log(sort(arr));
@McCarthey 非常厉害:tada:
function r(arr) {
const result = [];
while (arr.length) {
const top = arr.pop();
result.push(top); // 放入顶部
if (arr.length) {
const first = result.shift(); // 底部弹出
result.push(first); // 放入顶部
}
}
return result;
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
const result = r(arr);
console.log(result);
// [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]
function getOriginal(res) { // 需求的初始顺序数组 var ori = []
// 前两个直接取出,依次放入
ori.push(res.pop())
ori.push(res.pop())
// 超过2个,逆操作
while (res.length) {
// 取当前初始数组牌底移到自身牌顶
ori.push(ori.shift())
// 取当前结果数组牌顶放到初始数组牌顶
ori.push(res.pop())
}
return ori
}
var result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] console.log(getOriginal(result))
var a = [1,2,3,4,5,6,7,8,9,10,11,12,13];var b = []; while(a.length){ b.push(a.pop());a.length!=0&&b.push(b.shift()); } console.log(b) [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]
洗牌分两步骤: 一张卡牌出栈-->头插或尾插进入新组合 还原时也只需要两个步骤: 出栈或出列 --->插回原来的组合内 有一个需要注意的地方 : 牌的总数是奇数时 洗牌的最后一次操作是头插而不是尾插
function solution(arr) {
let res = [];
if (arr.length % 2 === 1) res.unshift(arr.shift());
while (arr.length) {
res.unshift(arr.pop())
if (arr.length) res.unshift(arr.shift())
}
return res;
}
按照结果数组插入的顺序反着来
var result = [1,2,3,4,5,6,7,8,9,10,11,12,13]
function getNum(arr) {
if(arr.length % 2 === 1) {
return arr.pop()
} else {
return arr.shift()
}
}
var original = []
while(result.length > 0) {
original.unshift(getNum(result))
}
console.log(original)
只要知道牌的张数就能通过一个状态去解决
function topic(arr) {
let sortArr = []
let oriArr = [...arr].reverse()
let length = arr.length
let isOdd = arr.length % 2 === 0 ? false : true
for (let i = 0; i < length; i++) {
isOdd ? sortArr.push(oriArr.shift()) : sortArr.push(oriArr.pop())
isOdd = !isOdd
}
return sortArr.reverse()
}
topic([1,2,3,4,5,6,7,8,9,10,11,12,13])
/**
* @desc
*
* @使用场景
*
* @[email protected]
* @Date 2019/8/28
**/
//倒带方式;
function recover(arr: number[]) {
let _new = [];
for (let i = 0, ilen = arr.length; i < ilen; i++) {
if (i % 2 === 1) {
//单
_new.push(arr.pop());
} else {
//双
_new.push(arr.shift());
}
}
return _new.reverse();
}
console.log(recover([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]));
//倒带 == 递归处理
function pickOne(array) {
if (array.length === 0) {
return [];
} else {
// if (array.length % 2 === 1) {
// return [array.shift()].concat(pickOne(array));
// } else {
// return [array.pop()].concat(pickOne(array));
// }
//尾递归优化
return [array[array.length % 2 === 1?"shift":"pop"]()].concat(pickOne(array))
}
}
console.log(pickOne([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]).reverse());
//从中间分
function pickMiddle(array:number[]):number[]{
if(array.length===0){
return [];
}
let index;
if( array.length % 2 === 1 ) { //取中间
index = Math.floor(array.length / 2)
} else {
index = array.length / 2
}
return [...array.splice(index,1),...pickMiddle(array)] ;
}
console.log(pickMiddle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]));
[
7, 8, 6, 9, 5, 10,
4, 11, 3, 12, 2, 13,
1
]
➜ src git:(master) ✗
➜ src git:(master) ✗ ts-node tt.ts
[
7, 8, 6, 9, 5, 10,
4, 11, 3, 12, 2, 13,
1
]
[
7, 8, 6, 9, 5, 10,
4, 11, 3, 12, 2, 13,
1
]
[
7, 8, 6, 9, 5, 10,
4, 11, 3, 12, 2, 13,
1
]
var reverse = arr => arr.reduce((a, b, c) => (c > 1 ? a.concat(a.shift(), b) : a.concat(b)), [])
var b = reverse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13].reverse())
console.log(b)
// [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]
console.log(getOrigin([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]
// 解题思路: 假设一个原数组, 以索引为值, 按照题意操作后得到一个新数组, 再和结果比对
function getOrigin(result) {
var origin = result.map(function (value, index) {
return index;
});
var clone = [].concat(origin);
var after = [];
var flag = true;
while (origin.length > 0) {
var first = origin.shift();
if (flag) {
after.push(first);
flag = false;
} else {
flag = true;
origin.push(first);
}
}
result.forEach(function (value, index) {
clone[after[index]] = value;
});
return clone;
}
` var cards1 = 'abcdefghijklm'.split('') var cards2 = 'abcdefghijklm'.split('') var newCards1 = [] function order (cards1) {
if (cards1.length===1) { newCards1.push(cards1[0]) newCards1.unshift('*') console.log(newCards1) cards2.forEach( (item,index)=>{ for (let i=1;i<14;i++) { if (item === newCards1[i]) cards2[index] = i } }) console.log(cards2) return false }else{ newCards1.push(cards1.splice(0,1)[0]) cards1.push(cards1.splice(0,1)[0]) order(cards1) } }
order(cards1) //输出[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中没有牌为止。
function sortPoke(list) {
const poke = []
poke.push(list.pop())
while (list.length) {
const y = poke.shift()
poke.push(y)
const x = list.pop()
poke.push(x)
}
return poke
}
sortPoke([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]
看我的
// 一堆牌,[1,2,3,4,5,6,7,8,9,10,11,12,13],依次将第一个放桌面上最上面,第二个放桌面牌堆的最下面,求最后桌面的牌堆顺序,牌底到牌顶顺序
const poker = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
const makePoker = _list => {
const rst = []
const list = _list.slice()
while (list.length) {
rst.push(list.shift())
list.length && rst.unshift(list.shift()) // 还有牌才会执行这一步
}
return rst
}
console.log(makePoker(poker)) // [ 12, 10, 8, 6, 4, 2, 1, 3, 5, 7, 9, 11, 13 ]
// 如果已知排好序后的牌是[1,2,3,4,5,6,7,8,9,10,11,12,13],求初始牌?
const reversePoker = _list => {
const rst = []
const list = _list.slice()
while (list.length) {
rst.unshift(list.pop())
list.length && rst.unshift(list.shift())
}
return rst
}
console.log(reversePoker(poker)) // [ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13 ]
// 下面是验证
console.log(makePoker(reversePoker(poker))) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
console.log(reversePoker(makePoker(poker))) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
后面发现我的题目与原题不同,下次再来写原题的答案~~
好了,原题答案也来了
// 一堆牌,[1,2,3,4,5,6,7,8,9,10,11,12,13],将牌堆第一张放到桌子上,
// 再将接下来的牌堆的第一张放到牌底,如此往复,牌底到牌顶顺序
const poker = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
const makePoker = _list => {
const rst = []
const list = _list.slice()
while (list.length) {
rst.push(list.pop())
list.length && list.unshift(list.pop()) // 还有牌才会执行这一步
}
return rst
}
console.log(makePoker(poker)) // [ 13, 11, 9, 7, 5, 3, 1, 10, 6, 2, 8, 12, 4 ]
// 如果已知排好序后的牌是[1,2,3,4,5,6,7,8,9,10,11,12,13],求初始牌?
const reversePoker = _list => {
const rst = []
const list = _list.slice()
while (list.length) {
rst.push(list.pop())
list.length && rst.push(rst.shift()) // 桌面的牌拿完了就不能再执行了,也就是桌面还有牌才执行
}
return rst
}
console.log(reversePoker(poker)) // [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]
// 下面是验证
console.log(makePoker(reversePoker(poker))) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
console.log(reversePoker(makePoker(poker))) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
好了,原题答案也来了
// 一堆牌,[1,2,3,4,5,6,7,8,9,10,11,12,13],将牌堆第一张放到桌子上, // 再将接下来的牌堆的第一张放到牌底,如此往复,牌底到牌顶顺序 const poker = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] const makePoker = _list => { const rst = [] const list = _list.slice() while (list.length) { rst.push(list.pop()) list.length && list.unshift(list.pop()) // 还有牌才会执行这一步 } return rst } console.log(makePoker(poker)) // [ 13, 11, 9, 7, 5, 3, 1, 10, 6, 2, 8, 12, 4 ] // 如果已知排好序后的牌是[1,2,3,4,5,6,7,8,9,10,11,12,13],求初始牌? const reversePoker = _list => { const rst = [] const list = _list.slice() while (list.length) { rst.push(list.pop()) list.length && rst.push(rst.shift()) // 桌面的牌拿完了就不能再执行了,也就是桌面还有牌才执行 } return rst } console.log(reversePoker(poker)) // [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ] // 下面是验证 console.log(makePoker(reversePoker(poker))) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ] console.log(reversePoker(makePoker(poker))) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
这里使用的是: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();
来自宝宝熊&&熊熊宝
- 发牌:
function f1(arr){
var newArr = [];
let status = true;
while (arr.length > 0) {
var index = arr.length - 1;
var item = arr.splice(index, 1)[0];
if (status || (index === 0)) {
newArr.push(item)
status = false;
} else {
arr.unshift(item)
status = true;
}
}
return newArr
}
- 还原
function f2(arr){
return arr.reverse().reduce((a, b, c) => {
return c > 1 ? a.concat(a.shift(), b): a.concat(b)
}, [])
}
先写出来正序的方法再改成倒叙,解决起来就会简单一些!
/**
* @description: 扑克牌问题正序
* @param {type} {number[]} A
* @return: {number[]} res
*/
var sortPokeOrder = function(A){
let res = [];
let length = A.length;
while(length > 0){
res.push(A.shift());
A.push(A.shift());
length--;
}
console.log('这是正序',res);
return res;
}
sortPokeOrder([1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7])
/**
* @description: 扑克牌问题倒序
* @param {type} {number[]} A
* @return: {number[]} res
*/
var sortPoke = function(A){
A.reverse();
let res = [];
let length = A.length;
while(length > 0){
res.unshift(A.pop());
A.unshift(A.pop());
length--;
}
res.reverse();
console.log('这是倒叙',res)
return res;
}
sortPoke([1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7])
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
}
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
let origin = [];
function sort(arr) {
if (arr.length == 0) {
return
}
let n = arr.pop();
origin.unshift(n);
// 最后一手不交换
if (arr.length > 0) {
let tail = origin.pop();
origin.unshift(tail);
}
console.log(origin.join(','))
sort(arr)
}
sort(arr)
console.log(origin.join(','))
/*
1,12,2,8,3,11,4,9,5,13,6,10,7
*/
function poker(arr) {
let collect = []
while (arr.length) {
collect.push(arr.pop())
if(collect.length>1 && arr.length) {
collect = [...collect.slice(1), collect[0] ]
}
}
return collect
}
/**
有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复;
最后桌子上的牌顺序为: (牌底) 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))
从牌桌拿回的时候,先要把最后一张置顶,也就是 result.unshift(result.pop())
。
之后就是基本操作
var data = [1,2,3,4,5,6,7,8,9,10,11,12,13]
function bar(data) {
let result = []
for(let i = data.length - 1; i >= 0; i--) {
if(result.length === 0 || result.length === 1) {
result.unshift(data[i])
continue
}
result.unshift(result.pop())
result.unshift(data[i])
}
console.log(result) //[ 1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7]
}
bar(data)
写一下自己的理解
// 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 = []; 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);})
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]
弄了一个图
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
function pokeOrigin(arr) {
let temp = arr.reverse();
let res = [];
while (temp.length > 0) {
if (res.length) {
res.unshift(res.pop())
}
res.unshift(temp.shift())
}
console.log(res);
return res
}
// var origin = [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7]
// function pokeCheck(arr) {
// let res = [];
// count = 0;
// while (arr.length) {
// if (count % 2 === 0) {
// res.push(arr.shift());
// } else {
// arr[arr.length - 1] = arr.shift();
// }
// count++;
// }
// console.log(res);
// return res;
// }
// pokeCheck(origin);
/** * 逆向:即从桌牌到手牌 * @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]
大神的思路总是这么清晰,我这个菜鸡只能学习一波。不过倒是发现了一个可优化的点:数组的 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]
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 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 } reverse([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]
看上的答案心都凉了,终于看到了一样的
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]
function reverse(cur) {
const res = []
let item
while (item = cur.pop()) {
res.push(item)
res.push(res.shift())
}
res.unshift(res.pop())
return res
}
你好,邮件已收到,我现在未上线,一会儿回复你。