记错了哈哈哈,今天本想打开阿里官网测试一下,结果发现它明天才考,我就想难道我错过了一场?一看今天是字节的笔试,哈哈哈。
算法题(牛客网)
1. 合并k个已排序的链表
归并排序,与普通的归并排序不同,这个不是排序数组,而是排序数组里的链表。
代码详情:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
return merge_sort(lists, 0, lists.size()-1);
}
//分割链表
ListNode* merge_sort(vector<ListNode*> &lists, int l, int r){
if (l == r) return lists[l]; //边界条件
if (l > r) return nullptr;
int mid = (l + r) / 2; //获取中间值
return merge(merge_sort(lists, l, mid), merge_sort(lists, mid + 1, r)); //排序并合并
}
//归并排序
ListNode* merge(ListNode* l, ListNode* r){
if(!l || !r) return l ? l : r; //判断是否为空
ListNode* root = new ListNode(0); //创建哨兵链表
ListNode* tail = root;
while(l && r){
if (l->val > r->val){ //选择小的
tail->next = r;
r = r->next;
}
else{
tail->next = l;
l = l->next;
}
tail = tail->next;
}
tail->next = l ? l : r; //将剩下的接到尾节点
return root->next;
}
};
2. 字符串的排列
递归枚举。
class Solution {
public:
vector<string> Permutation(string str) {
int n = str.size();
set<string> res; //创建set,防止重复数据
helper(str,n,0,res);
return vector<string>({res.begin(),res.end()});
}
//辅函数
void helper(string str,int n,int pos,set<string>& res){
if (pos+1 >= n){ //如果长度相等则返回
res.insert(str);
return;
}
for(int i = pos;i < n; ++i){
if (str[pos] == str[i] && i != pos){ //如果相同则无序交换
continue;
}
swap(str[pos],str[i]); //在pos位置固定一个字符
helper(str,n,pos+1,res);
swap(str[pos],str[i]); //回溯
}
}
};
3. 接雨水问题
双指针。
代码详情:
class Solution {
public:
/**
* max water
* @param arr int整型vector the array
* @return long长整型
*/
long long maxWater(vector<int>& arr) {
// write code here
int n = arr.size();
int left = 0, right = n - 1; //创建左右指针
int leftMax = 0, rightMax = 0; //左右最高值
int ans = 0; //记录最终答案
while(left < right){
leftMax = max(leftMax, arr[left]); //更新最高挡板
rightMax = max(rightMax,arr[right]);
if (arr[left] < arr[right]){ //短板效应
ans += leftMax - arr[left++];
}
else{
ans += rightMax - arr[right--];
}
}
return ans;
}
};
面试题
1. C++11新特性
1. auto & decltype:类型推导
2. 左值右值:左值:可以取地址并且有名字的东西就是左值。右值:不能取地址的没有名字的东西就是右值。
3. 列表初始化
4. std::function & std::bind & lambda表达式
5. 智能指针
6. nullptr
7. const/constexpr
8. sizeof
9. 内存对齐
2. 智能指针
什么是智能指针?能够利用对象生命周期控制程序资源的技术。
有什么作用?可以防止内存泄漏、二次释放等问题。
3. lambda表达式
什么是lambda表达式?定义了一个匿名函数,并且可以捕获一定范围内的变量。
优点:
1. 声明式编程风格:匿名定义目标函数,可维护性高。
2. 简洁:避免代码膨胀、功能分散。
3. 在需要的时间和地点实现功能闭包,使程序更灵活。
缺点:
1. 代码可读性变差。
2. 学习难度高。
3. 非并行计算中,很多计算没有传统的for性能高。
4. 不容易调试。
4. 强枚举类型
先了解传统枚举类型:它是由用户定义的若干枚举常量的集合。枚举值对应整型数值,默认从零开始。
传统枚举类型存在问题:
1. 同作用域同名枚举会报错。
2. 用户无法自定义枚举常量定义类型。 (C++11可以)
3. 枚举常量占用存储空间及符号不确定。
因此强枚举类型诞生。优点:
1. 强作用域。可以不同枚举之间取同名成员。
2. 转换限制,不再与整型发生隐式转换。
3. 可以指定底层类型。
5. C++编译连接过程
源代码 -》 编译器 -》 汇编代码 -》 汇编器 -》目标代码(机器指令) -》 连接器 -》 可执行程序。
今天字节笔试,难度中等吧,就是有些犯傻的时候,知道自己递归和深度搜索方面薄弱,明天加强一下,今天练的两道困难笔试,占了超多时间,明天阿里笔试加油!