重思路非代码。基础的思路搞懂了,变形题目顺着思考基本都能写出来!以下是自己8年技术面试以来总结的算法考点!
基础(要消化的)
基础查找 二叉树 链表 排序
二分查找
int binarySearch(vector<int> &nums, int target) {
// write your code here
if (nums.empty()) {
return -1;
}
int start = 0;
int end = nums.size() - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] >= target) { // 有重复的输出第一个
end = mid;
} else {
start = mid;
}
/*
if (nums[mid] <= target) { // 有重复的输出最后一个
start = mid;
} else {
end = mid;
}
*/
}
if (nums[start] == target) {
return start;
}
if (nums[end] == target) {
return end;
}
return -1;
}
链表逆序
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
// 注意的是先画图, 代码自然就能写出来
ListNode* prev = nullptr;
ListNode* cur = head;
while (cur != nullptr) {
ListNode* tmp = cur->next;
cur->next = prev;
prev = cur;
cur = tmp;
}
return prev;
}
};
二叉树遍历
// 前序
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if (root == nullptr) {
return {};
}
stack<TreeNode*> s;
// s.push(root);
vector<int> res;
while (!s.empty() || root) {
if (root) {
res.push_back(root->val);
s.push(root);
root = root->left;
} else {
root = s.top();
s.pop();
root = root->right;
}
}
return res;
}
};
// 中序
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) {
res;
}
stack<TreeNode*> s;
// s.push(root);
while (!s.empty() || root) {
if (root) {
s.push(root);
root = root->left;
} else {
root = s.top();
res.push_back(root->val);
s.pop();
root = root->right;
}
}
return res;
}
};
// 后序
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
if (root == nullptr) {
return {};
}
vector<int> res;
stack<TreeNode*> s;
while (!s.empty() || root) {
if (root) {
s.push(root);
res.push_back(root->val);
root = root->right;
} else {
root = s.top();
s.pop();
root = root->left;
}
}
std::reverse(res.begin(), res.end());
return res;
}
};
// 层序
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if (root == nullptr) {
return res;
}
queue<TreeNode*> q;
q.push(root);
TreeNode split = TreeNode(INT_MAX);
q.push(&split);
vector<int> layer;
while (!q.empty()) {
TreeNode *cur = q.front();
q.pop();
if (cur == &split) {
res.push_back(layer);
layer.clear(); // 注意别忘记清理
if (!q.empty()) {
q.push(&split);
}
} else {
layer.push_back(cur->val);
if (cur->left) {
q.push(cur->left);
}
if (cur->right) {
q.push(cur->right);
}
}
}
return res;
}
};
N叉树
class Solution {
public:
vector<int> preorder(Node* root) {
vector<int> res;
if (root == nullptr) {
return res;
}
//helper(root, res); // 递归版本
stack<Node*> s;
s.push(root);
while (!s.empty()) {
Node* cur = s.top();
s.pop();
if (cur != nullptr) {
res.push_back(cur->val);
}
std::reverse(cur->children.begin(), cur->children.end());
for (auto &node : cur->children) {
s.push(node);
}
}
return res;
}
/*void helper(Node* root, vector<int>& out) {
if (root == nullptr) {
return;
}
out.push_back(root->val);
for (int i = 0; i < root->children.size(); ++i) {
helper(root->children[i], out);
}
}
*/
};
基础排序
/* 归并排序 */
// merge
void merge(vector<int>& nums, int low, int high, vector<int>& tmp) {
int mid = (low + high) / 2;
int leftIndex = low;
int rightIndex = mid + 1;
int resLeftIndex = leftIndex;
while (leftIndex <= mid && rightIndex <= high) {
// leftIndex 135
// rightIndex 246
// resLeftIndex 123456
if (nums[leftIndex] >= nums[rightIndex]) {
tmp[resLeftIndex++] = nums[rightIndex++];
}
else {
tmp[resLeftIndex++] = nums[leftIndex++];
}
}
while (leftIndex <= mid) {
tmp[resLeftIndex++] = nums[leftIndex++];
}
while (rightIndex <= high) {
tmp[resLeftIndex++] = nums[rightIndex++];
}
for (int i = low; i <= high; ++i) { // 易错点 <=
nums[i] = tmp[i];
}
}
// 分治
void divideConquer(vector<int>& nums, int low, int high, vector<int>& tmp) {
if (low >= high) {
return;
}
// 分而治之
divideConquer(nums, low, (high + low) / 2, tmp);
divideConquer(nums, (high + low) / 2 + 1, high, tmp);
// 合并有序数组
merge(nums, low, high, tmp);
}
void mergeSort(vector<int>& nums) {
if (nums.empty()) {
return;
}
vector<int> tmp(nums.size());
divideConquer(nums, 0, nums.size() - 1, tmp);
}
int main()
{
vector<int> nums = { 2, -1, 4, 55, 0, 67, -23, 5, 9 };
//quickSortNotR(nums, 0, nums.size() - 1);
mergeSort(nums);
for (auto item : nums) {
cout << item << " ";
}
cout << endl;
return 0;
}
// 快速排序
int getPartSortIndex(vector<int>& nums, int low, int high) {
int tmp = nums[low]; // TODO:随机取值
int i = low;
int j = high;
while (i <j) {
while (i < j && nums[j] >= tmp) {
j--;
}
nums[i] = nums[j];
while (i < j && nums[i] <= tmp) {
i++;
}
nums[j] = nums[i];
}
nums[i] = tmp;
return i;
}
// 递归版本
void quickSort(vector<int>& nums, int low, int high) {
if (low >= high) {
return;
}
int index = getPartSortIndex(nums, low, high);
quickSort(nums, low, index - 1);
quickSort(nums, index + 1, high);
}
// 非递归版本
void quickSortNotR(vector<int>& nums, int low, int high) {
if (low >= high) {
return;
}
stack<int> s;
s.emplace(low);
s.emplace(high);
while (!s.empty()) {
int right = s.top();
s.pop();
int left = s.top();
s.pop();
int index = getPartSortIndex(nums, left, right);
if (index - 1 > left) {
s.emplace(left);
s.emplace(index - 1);
}
if (index + 1 < right) {
s.emplace(index + 1);
s.emplace(right);
}
}
}
典型常考类型及题目(需要面试前回顾下)
题目列举
二分
链表与数组
二叉树与分治
二叉树翻转——注意:用递归、DFS、栈分别实现下
排序
广度优先
哈希与堆(应急不优先)
第K个大或者小元素
异位词
两根指针(应急不优先)
深度优先(应急不优先)
动态规划(应急不优先)
171万+

被折叠的 条评论
为什么被折叠?



