小米笔试考了3道编程题,1个小时内做完, 考完给我的感觉是, 1.回去要好好复习一下String类了,成员函数都忘光光。 2.还是要多刷leetcode的题目
第一题:
有一个字符串系列,其组成是{A,B,...,Z, AA,AB,...,AZ,BA,BB,...,BZ, ..., ZA,...,ZZ, AAA,...,AAB,...,ZZA,...,ZZZ,...},即长度为k的字符串一共有26^k个。 要求输入一个n返回第n个字符串。
这题在leetcode上有原题
https://leetcode.com/problems/excel-sheet-column-title/
AC的代码:
class Solution { public: string convertToTitle(int n) { string result; while (n>0) { int remaind = n-(n-1)/26*26; n = (n-1)/26; result = (char)('A'+remaind-1) + result; } return result; } };
注意的是不要用result.insert(0, &ch);这样结尾会多出一个不知名的字符,C++的string类重载了+运算符,直接加到前面就行了。
这题是一个进制转换的问题,A-Z对应到十进制是1-26
字符串到整数的换算规则,举个例子,比如ABCD 换算过去就是 1*26^3+2*26^2+3*26^1+4*26^0=19010
int remaind = n-(n-1)/26*26; 的含义是取字符串的最后一位,设最后一位为r,由上面的公式我们知道,如果去掉最后一位,那么这个整数可以表示为26的倍数,记m=(n-1)/26,m经过了一次下取整实际上就是这个倍数,那么n可以表示为n=m*26+r的形式。
而n = (n-1)/26实际上是去掉最后一位,即得到m这个数,那么怎么去掉的呢?
首先分子为n-1,为什么要减这个1,请思考这个问题,如果最后一位是Z(26),那么我要把它去掉,直接除以26不行,因为会变成n/26=m+1,而我要的是这个m。因此如果我从n上减掉1,就变成了(n-1)/26=(m*26+r-1)/26=m+(r-1)/26,由于r<=26,因此(r-1)/26下取整以后就是0.这样我们就让最后一位蒸发了。
有了以上分析,我们还可以简化一下代码:
class Solution { public: string convertToTitle(int n) { string result; while (n>0) { --n; result = (char)('A'+n%26) + result; n /= 26; } return result; } };
这里的n%26就是上面的remaind-1
第二题:
二叉树的层次遍历, 要求一层一行输出。
这题在leetcode上有,https://leetcode.com/problems/binary-tree-level-order-traversal/
自己写的解法:
我用了两个整数,一个用来保存上一层的剩余节点数,另一个用来保存当前层的节点数。
每当队列头元素出列时上一层剩余节点数减1,如果有新节点加入队列,则当前层节点数加1.在上一层剩余节点数减小到0之前加入的节点都会被加到当前层。当上一层节点数减到0时,完成一层遍历,把上一层push到vecor里去。
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> levelOrderVec; if (!root) return levelOrderVec; vector<int> curLevel; TreeNode* p = root; queue<TreeNode*> treeNodeQueue; treeNodeQueue.push(p); //上一层的节点数 int nLastLevelNodes = 1; //当前层的节点数 int nCurLevelNodes = 0; while (!treeNodeQueue.empty()) { p = treeNodeQueue.front(); treeNodeQueue.pop(); curLevel.push_back(p->val); --nLastLevelNodes; if (p->left) { treeNodeQueue.push(p->left); ++nCurLevelNodes; } if (p->right) { treeNodeQueue.push(p->right); ++nCurLevelNodes; } //上一层所有节点已经出队列 if (nLastLevelNodes==0) { levelOrderVec.push_back(curLevel); curLevel.clear(); nLastLevelNodes += nCurLevelNodes; //更新上一层节点数 nCurLevelNodes = 0; //并将当前层节点数清0 } } return levelOrderVec; } };
结果显示我只击败了7%的人。。You are here! Your runtime beats 7.00% of cpp submissions.
34 / 34 test cases passed.
|
Status:
Accepted |
Runtime: 8 ms
|
Submitted: 0 minutes ago
|
这题还有个变种,就是从底部开始遍历,参见https://leetcode.com/problems/binary-tree-level-order-traversal-ii/
这题一个较简单解法是先用一个栈保存每层遍历,最后再倒到vector里。
其实层次遍历还可以用递归来实现。
第三题:
大数乘法。给定两个整数, 用字符串存储, 要求对输入判断格式, 还要返回二者的乘积。
这题我忘记判断输入合法了。由于String类忘了,用C实现起来很蛋疼, 还用到了栈,因为不知道乘出来多少位,因此从低位开始计算,最后再倒过来。
也可以在string上直接插入,就是不知道和堆栈比起来哪个效率高一点。
这题在leetcode上也有原题 https://leetcode.com/problems/multiply-strings/
有几个地方我犯了错,一个是记得把字符转为整数, 我那时拿着ascii码直接做了乘法 ;第二个是写成了对应位的乘法