1.2 中国象棋将帅问题。
中国象棋中,“将”和“帅”都有九个位置可以选择放置,找出所有将和帅不再一列的放置方法,要求只能使用一个字节存储变量。
这道题的难点在于只能使用一个字节存储变量。第一种思路是用一个字节的高四位和底四位分别保存将和帅的位置,一种方法是使用位操作,略显麻烦,另外一种方法就是使用位域(bit-field),操作比较简单;第二种思路就是利用二维矩阵与一维的对应关系,通过 /C 和 %C 操作得到元素的行号和列号(C为二维矩阵的列数),如下图。
0 | 1 | 2 | |
0 | 0 | 1 | 2 |
1 | 3 | 4 | 5 |
2 | 6 | 7 | 8 |
因为以前只是知道位域这个概念,没有用过,就写一下代码熟悉一下吧。
1 #include2 3 struct 4 { 5 unsigned char a:4; 6 unsigned char b:4; 7 } i; 8 9 int main()10 {11 for (i.a = 1; i.a <= 9; i.a++)12 for (i.b = 1; i.b <= 9; i.b++)13 if (i.a%3 != i.b%3)14 printf("A = %d, B = %d\n", i.a, i.b);15 return 0;16 }
4.3 买票找零
有2n个人在排队买门票,门票50一张,其中有n个人手持50的钞票,n个人手持100元的钞票。开始时售票处没有零钱,问这2n个人有多少中排队方式,使得售票处到最后都可以找到零钱。
关于卡特兰数(Catalan)的问题。h(0)=1, h(1)= 1, 当n>=2时,h(n) = h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)*h(0), h(n) = C(2n, n)/(n+1)。
与卡特兰数相关的问题有:
- 矩阵链乘的括号化方案数。
- 多边形的三角剖分方案数。
- n个节点构成不同二叉树个数。
- 圆上n条直线不相交方案数。
- 从(0, 0)到(n, n)不越过连线的走法数。
3.6 判断两个链表是否相交
因为单链表的特点,实际是就是判断两个链表是否有公共节点问题,判断最后一个节点就好了。《剑指Offer》第37题介绍了求两个链表第一个公共节点的方法。
3.7 队列中最大值操作问题
在正常队列基础上增加取最大值操作。其实就是《剑指Offer》第7题:用两个栈实现队列和第21题:包含min函数的栈的结合。可是这道题还是没能做出来...
2.9 斐波那契数列
正常的解法就是递推,不过公式+二分的解法在处理大数据的时候还是挺好的,将时间复杂度优化到了O(log2n)。
2.10 寻找数组中的最大值和最小值
这个题的优化就是分成两个一组,这样只需一次比较就得出的该组的最大值和最小值,将比较次数较少了n/2次。