在面试手撕代码时,
面对的代码环境常常不是类似于leetcode那样的核心代码填空,
而是需要你自己去搭建一个完整的代码框架, 处理输入输出,
以及边界条件等问题.
头文件
在使用ACM模式时, 需要知道常用的方法对应的头文件:
- <bits/stdc++.h>: 包含了几乎所有的标准C++库, 适合竞赛使用,
但编译速度较慢.
- : 定义了各种数据类型的极限值, 如
INT_MAX,
INT_MIN
- : 提供字符处理函数, 如
isdigit()
- : 包含通用工具函数, 如
abs(),
rand()
- : 还提供了
stoi()
- : 提供时间和日期函数, 如
time(),
clock()
- 一般与 一起使用, 用于生成随机数, 如
srand(time(0))
一般输入处理技巧
处理多组输入:
1 2 3 4 5 6 7 8 9
| #include <iostream> using namespace std;
int main() { int n; while (cin >> n) { } }
|
这里的
while (cin >> n) 会持续读取输入直到没有更多数据,
适用于多组测试数据的情况.
整行读取, 可以消除换行符影响:
1 2 3 4 5 6 7 8 9 10 11
| #include <iostream> #include <string> using namespace std; int main() { string line; while (getline(cin, line)) {
} }
|
使用
getline 可以读取整行输入, 避免换行符对输入处理的影响.
下次读取时会自动跳过换行符.
或者使用 cin.ignore() 来忽略换行符:
1 2 3 4 5 6 7 8 9
| #include <iostream> using namespace std; int main() { int n; while (cin >> n) { cin.ignore(); } }
|
处理多行输入:
1 2 3 4
| #include <iostream> #include< using namespace std;
|
创建链表
在处理链表输入时,
通常会以空格分隔的整数形式提供链表节点值.
一行输入表示一个链表. 下面是一个示例代码,
展示如何从输入中创建链表并传入到处理函数中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include<iostream> #include<sstream> #include<string> using namespace std;
struct ListNode{ int val; ListNode* next; ListNode(int v) : val(v), next(nullptr) {} };
ListNode* createList(){ string line; getline(cin, line); if(line.empty()) return nullptr;
stringstream ss(line); int num;
ListNode* dummy = new ListNode(-1); ListNode* tail = dummy;
while(ss >> num){ tail->next = new ListNode(num); tail = tail->next; }
return dummy->next; }
void printList(ListNode* node){ while(node){ cout << node->val << ' '; node = node->next; } cout << endl; }
int main(){ ListNode* head = createList(); ListNode* ret = reverseList(head); printList(ret); return 0; }
int main(){ ListNode* list1 = createList(); ListNode* list2 = createList(); ListNode* ret = mergeTwoLists(list1, list2); printList(ret); return 0; }
|
创建二叉树
在处理二叉树输入时,
通常会以层序遍历的形式提供二叉树节点值,
使用空字符串或特定标记(如 null)表示空节点.
下面是一个示例代码, 展示如何从输入中创建二叉树并传入到处理函数中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include<iostream> #include<sstream> #include<queue> using namespace std;
struct TreeNode{ int val; TreeNode* left; TreeNode* right; TreeNode(int x): val(x), left(nullptr), right(nullptr) {} };
TreeNode* createTree(){ string line; getline(cin, line); if(line.empty()) return nullptr;
stringstream ss(line); string valstr; ss >> valstr; if(valstr=="null") return nullptr;
TreeNode* root = new TreeNode(stoi(valstr)); queue<TreeNode*> q; q.push(root);
while(!q.empty()){ TreeNode* cur = q.front(); q.pop();
if(ss >> valstr){ if(valstr!="null"){ cur->left = new TreeNode(stoi(valstr)); q.push(cur->left); } }
if(ss >> valstr){ if(valstr!="null"){ cur->right = new TreeNode(stoi(valstr)); q.push(cur->right); } } } return root; }
int main(){ TreeNode* root = createTree(); int depth = maxDepth(root); cout << depth; return 0; }
int main(){ TreeNode* tree1 = createTree(); TreeNode* tree2 = createTree(); bool isSame = isSameTree(tree1, tree2); cout << (isSame ? "True" : "False"); return 0; }
|