行列有序矩阵求第K个数

问题:n*n的行列有序的矩阵M,求第K大的数。行列有序是指每行、每列都是有序的。

最直接的办法就是给整个矩阵排序,然后找第K大的数。复杂度是(O(n^2logk))。其实还有更快的办法。

假设行列都是增序。注意到在矩阵的对角线上中任选一点x,右下角的矩阵里面的数都大于或等于x,而这里包含了(x^2)个数。因此,必然可以找到一个位置x,使得 ((x+1)^2leq n-kleq x^2) 。 这样K就在 M(x+1, x+1) .. M(x+1, n) 和 M(x+1, x+1) .. M(n, x+1) 以及 x 这三个范围内。

对这个范围内的数字排序,找第K个数字,复杂度是 (O(nl[......]

阅读全文

字节按位逆序

问题:给一个8位的字节,按位逆序。第一反应给了个简单的做法:

unsigned short intreverse_bit(unsigned short int b)
{
    unsigned short int r = 0;
    for (int i=0; i<8; i++) {
        b >> = 1
        r = (r << 1) | (b & 1);
    }
    return r;
}

每次循环,r左移一位,b取最后一位填充到r的最后一位上,这个解答需要做8次循环,32次操作(左移一次,加法一次,右移一次,按位与一次)。很明显还有更好的做法。

unsigned short int reverse_bit(unsigned short int b)
{
	b = b << 4 + b >> 4;    // &11110000, 56781234
	b = (b & 0x33) << 2 + (b & 0xCC) >> 2;    // &11001100, 78563412
	b = (b & 0x55) << 1 + (b & 0xAA) >> 1;    // &10101010, 87654321

	return b;
}

只需13次操作。

[......]

阅读全文

编程之美 1.2 中国相帅问题的一个简洁解法

题目意思大概是,象棋棋盘上只有一相一帅,只能在9宫格内移动,且不能对面。要求给出相帅所有的位置的可能性,只能用一个变量。

只用一个变量,第一感是用位操作。给九宫格编个号:
1 2 3
4 5 6
7 8 9
遍历所有的位置,如果 位置编号 mod 3相同,说明在同一列中。按此思路,书中位操作的解法略显繁杂。这里一个简洁的的解法是:

如果不用位操作的话,另外一个解法比较赞: