面试杂题
1:
字符串中,把所有星号都移动到字符串的最前端,举个例子:字符串*ad**das*wq*,处理后变成 *****adadswq
思路:可以建立双指针,第一个指针(记为x)每次指向字符串的最后一个星号的位置,第二个指针(记为y),指向在指针x左边的那些位置当中,从右往左遍历第一个不是星号的字符的位置,然后交换x,y指针所在处的值,接着进行下一次操作。
重要步骤实现代码如下:
void sovle() { int len = strlen(str); int x = len - 1; while (x >= 0 && str[x] != '*')x--; int y = x - 1; while (y >= 0 && str[y] == '*')y--; while (x>=0&&y>=0) { swap(str[x], str[y]); while (x >= 0 && str[x] != '*')x--; while (y >= 0 && str[y] == '*')y--; } }
2:
知一个数n的十进制,求其二进制数中1的个数:
利用n&(n-1),每次可以去掉当前n二进制当中的最后一个1.
代码:
int cnt = 0; cin >> n; while (n) { n &= n - 1; cnt++; } cout << cnt << endl;
3:
一个n*m的矩形(像素)方阵,每个像素都是1*1的正方形。问n*m的矩形当中一共能构造处多少的子矩形和多少的子正方形。
思路:先考虑n,m比较大的一者,不妨设m比较大,求正方形的个数:首先正方形的边长一定不能超过n,我记当前考虑的正方形的边长为x,在为m的边长当中,长为x的边长一共可以有m-x+1种放法。同理,在长为n的边中,有n-x+1种放法。所以在n*m矩形中,边长为x的正方形一共有(m-x+1)(n-x+1)种,x从1开始便利到n,即是所有的正方形的个数。
再考虑长方形的个数,同理,所有长方形个数就是(1+2+...+n)(1+2+...+m)。
4:
利用O(1)时间以及O(1)空间,实现在线的查找当前栈中的最大值。
思路:记当前栈中的最大值为max_num,并且当前想要push进栈中的元素记为x;这时我们的push,pop的实现机制如下:
push操作:
如果当前想要压入的元素值x,那么实际压入栈的值为x'=max_num-x
接着如果要压入的元素值x>max_num,即x'<0时,max_num赋值为x;
pop操作:
如果当前的要抛出的栈顶元素值x'>=0,由push时的操作得到真正的值x=max_num-x'
如果当前的栈顶元素x'<0,由push时候的式子知真正的元素值就是max_num,并且max_num也要进行更新,即max_num=x+x'=max_num+x';
代码参考:
int st[N_MAX]; int t = 0,max_num=0; void push(int x) { st[t++] = max_num - x; if (st[t-1] < 0)max_num = x; } int pop() { if (!t)return -1; int top = st[--t]; if (top >= 0) { return max_num - top; } else { int res = max_num; max_num = max_num + top; return res; } } int get_max() { if (!t)return -1; else return max_num; }
5:
把一个浮点数转化成字符串类型
思路:把浮点数的小数与整数部分分开考虑。整数部分拆开,比较容易。小数部分记为y,可以不断的y=y*10,进上一位再强制转换整形,即可得到当前小数点后第一位,不断重复此操作即可,注意精度问题。
参考代码:
string transform(double x) { string s = ""; int a = (int)x;//整数部分 double b = x - a;//小数部分 if (a == 0)s += '0'; else while (a) { s += a % 10 + '0'; a /= 10; } reverse(s.begin(), s.end()); s += '.'; double y = b,tmp=0.1; while (b>EPS) { b -= tmp*(int)(y * 10); s += (int)(y*10)+ '0'; y = y*10 - floor(y*10); tmp /= 10; } return s; }