笔试算法题(21):将stack内外颠倒 & 判断扑克牌顺子
2014-05-22 09:26
344 查看
出题:要求用递归将一个栈结构的元素内外颠倒;
分析:
本题再次说明系统栈是程序员最好的帮手,但递归度较高所以时间复杂度较大,可以使用空间换时间的方法(额外数组保存栈元素,然后逆向压入);
第一层递归(清空栈元素,并使用系统栈保存):[1,2,3,4,5],栈顶元素为1,将1弹出之后,递归处理[2,3,4,5];
第二层递归(将栈顶元素插入到栈底,同样使用系统栈保存):当[2,3,4,5]已经逆序之后,需要将1插入到栈底,所以将1作为参数传递到递归调用中,之后递归处理2和[3,4,5];
解题:
出题:从扑克牌中随机抽出5张牌,判断是否为顺子(顺子则为连续的5张牌,A为1, 2-10为其本身,J为11,Q为12,K为13,大小王可代替任意数字,13在中间的连续不算顺子);
分析:
解法1:首先确认5个数中除0之外没有其他重复的数字,如果有则失败,并且找到最大值max,最小值min和0的个数(count0);然后如果max-min<=4则成立,否则失败,此方法不用排序;
解法2:首先对5个数字进行排序,然后使用king索引最右边的0,使用index遍历king之后的所有元素,一旦遇到next与current有大于 1的差值,则将king向左移动并判断是否超出数组下限,如果超出则返回false;如果next到达数组上限则返回true;
解法3:将大小王的大小看做0,首先对5个数字进行排序,然后统计0的个数,然后统计数组中连续数字是否有空缺,如果没有说明有重复出现的牌,则失败;如果空缺数大于统计的0的个数,则说明王不够用于替换所有的空缺,失败;
所以判断K个数字是否连续的最直接的方法就是判断其max和min的差值是否小于K个数字;
解题:
分析:
本题再次说明系统栈是程序员最好的帮手,但递归度较高所以时间复杂度较大,可以使用空间换时间的方法(额外数组保存栈元素,然后逆向压入);
第一层递归(清空栈元素,并使用系统栈保存):[1,2,3,4,5],栈顶元素为1,将1弹出之后,递归处理[2,3,4,5];
第二层递归(将栈顶元素插入到栈底,同样使用系统栈保存):当[2,3,4,5]已经逆序之后,需要将1插入到栈底,所以将1作为参数传递到递归调用中,之后递归处理2和[3,4,5];
解题:
class MyStack { private: int *array; int capability; int top; public: MyStack(int cap=5): array((int*)malloc(sizeof(int)*cap)), capability(cap), top(0) {} ~MyStack() {delete [] array;} bool isFull() { return top == capability; } bool isEmpty() { return top == 0; } int freeSlot() { return capability - top; } /** * top当前的位置就是下一个push元素所在的slot * */ bool push(int n) { if(isFull()) return false; array[top++]=n; return true; } bool pop(int *n) { if(isEmpty()) return false; *n=array[--top]; return true; } void ShowStack() { int temp=top-1; printf("\n"); for(int i=0;i<=temp;i++) printf("%d, ",array[i]); printf("\n"); } }; void AddToBottom(MyStack *stack, int top) { int curTop; if(stack->pop(&curTop)) { AddToBottom(stack, top); stack->push(curTop); }else stack->push(curTop); } void ReverseStack(MyStack *stack) { int top; if(stack->pop(&top)) { ReverseStack(stack); AddToBottom(stack, top); } }
出题:从扑克牌中随机抽出5张牌,判断是否为顺子(顺子则为连续的5张牌,A为1, 2-10为其本身,J为11,Q为12,K为13,大小王可代替任意数字,13在中间的连续不算顺子);
分析:
解法1:首先确认5个数中除0之外没有其他重复的数字,如果有则失败,并且找到最大值max,最小值min和0的个数(count0);然后如果max-min<=4则成立,否则失败,此方法不用排序;
解法2:首先对5个数字进行排序,然后使用king索引最右边的0,使用index遍历king之后的所有元素,一旦遇到next与current有大于 1的差值,则将king向左移动并判断是否超出数组下限,如果超出则返回false;如果next到达数组上限则返回true;
解法3:将大小王的大小看做0,首先对5个数字进行排序,然后统计0的个数,然后统计数组中连续数字是否有空缺,如果没有说明有重复出现的牌,则失败;如果空缺数大于统计的0的个数,则说明王不够用于替换所有的空缺,失败;
所以判断K个数字是否连续的最直接的方法就是判断其max和min的差值是否小于K个数字;
解题:
/** * 解法1: * */ bool BetterVersion(int *array, int length) { int hash[14]; int max=array[0],min=array[1]; /** * 使用一个14个元素的int数组表示13个数字和王(0) * 全部初始化为0 * */ for(int i=0;i<14;i++) hash[i]=0; for(int i=0;i<length;i++) { if(array[i]==0) hash[0]++; else { /** * max和min仅在1到13之间统计 * 并且一旦某个数字出现两次,则失败 * */ if(hash[array[i] == 0) hash[array[i]=1; else return false; if(array[i]>max) max=array[i]; if(array[i]<min) min=array[i]; } } /** * 只要max和min相差值小于5,说明肯定可以连续 * */ if(max-min<=4) return true; else return false; }/** * 解法2: * */ bool DetermineJunko(int *array, int length) { /** * 使用插入排序对数组进行排序 * */ InsertSort(array, 0, length-1); /** * 计算王的个数,使用king索引,缺省值为-1 * */ int king=-1; for(int i=0;i<length;i++) { if(array[i]==0) king++; else break; } /** * 从king后面一个位置开始,判断current和next索引 * 的元素是否连续 * 如果是则current和next向右移动 * 如果不是则向左移动king表示使用王替换 * 并且向右移动current和next * 如果king已经到-1则失败 * 如果next已经到达数组末尾则成功 * */ int current=king+1, next=king+2, diff=0; while(next < length) { if(array[current]+1==array[next]) { current++;next++; } if (array[current]==array[next]) { return false; } else { diff=array[next]-array[current]; for(int i=1;i<diff;i++) { if(king>-1) { king--; current++;next++; } else return false; } } } return true; }
相关文章推荐
- 笔试算法题(25):复制拥有多个指针的链表 & 判断二元树B是否为A的子树
- 笔试算法题(29):判断元素范围1到N的数组是否有重复数字 & 计算整数的7倍
- 笔试算法题(19):判断两条单向链表的公共节点 & 字符集删除函数
- 笔试算法题(27):判断单向链表是否有环并找出环入口节点 & 判断两棵二元树是否相等
- 算法题7 判断扑克牌中的顺子
- 算法题7 判断扑克牌中的顺子
- 【算法04】判断扑克牌中的顺子
- 笔试算法题(10):深度优先,广度优先以及层序遍历 & 第一个仅出现一次的字符
- 判断扑克牌中的顺子
- 零零散散学算法之判断集合的相同&相似性
- 笔试算法题(07):还原后序遍历数组 & 半翻转英文句段
- 一道笔试题(扑克牌顺子)
- 华为机试题&nbsp;扑克牌判断
- 判断点在多边形内外的简单算法
- 笔试算法题(04):实现 string & memcpy & strcpy & strlen
- 笔试算法题(05):转换BST为双向链表 & 查找栈中的最小元素
- 扑克牌中的顺子(网易2014.3.16笔试offerP226)
- 【100题】第六十六~第七十题(颠倒栈、扑克牌顺子和掷骰子概率、数字数组排成最小数、求旋转数组中最小值、全排列)
- 【数据结构&&算法】腾讯2012年实习生笔试加分题
- 判断扑克牌的顺子