面试手撕合集
已知高频面试题
一、链表
1.移除链表元素
class Solution { public: ListNode* removeElements(ListNode* head, int val) { ListNode* dummmyhead = new ListNode(0); ListNode* cur = dummmyhead; dummmyhead->next = head; while(cur->next != nullptr){ if (cur->next->val == val){ cur->next = cur->next->next; } else cur = cur->next; } return dummmyhead->next; } };
2.反转链表
class Solution { public: ListNode* reverseList(ListNode* head) { if (head == nullptr) return head; ListNode* pre = nullptr; ListNode* cur = head; while(cur != nullptr){ ListNode* tmp = cur->next; cur->next = pre; pre = cur; cur = tmp; } return pre; } };
3.两两交换链表节点
class Solution { public: ListNode* swapPairs(ListNode* head) { if (head == nullptr || head->next == nullptr) return head; ListNode* dummy = new ListNode(0); dummy->next = head; ListNode* pre = dummy; ListNode* cur = head; while(cur != nullptr && cur->next != nullptr){ ListNode* tmp = cur->next->next; cur->next->next = cur; pre->next = cur->next; cur->next = tmp; pre = cur; cur = tmp; } return dummy->next; } };
4.删除链表中的倒数第N个节点
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* dummy = new ListNode(0); dummy->next = head; ListNode* pre = dummy; ListNode* cur = head; while(n--) cur = cur->next; while(cur != nullptr){ cur = cur->next; pre = pre->next; } pre->next = pre->next->next; return dummy->next; } };
一、设计模式
1.单例模式
2.观察者模式(信号与槽、智能指针?)
二、排序算法
1.插入排序
2.冒泡排序
3.快速排序
4.归并排序
5.堆排序
三、查找算法
1.二分查找
四、字符串题
1.实现strStr()
2.实现strcpy()
3.实现strcmp()
4.回文字符串
5.划分字符区间
这里用到的技巧是当我感觉需要多次进入某个循环(至少进入一次)但后续进入的条件不明确时,就用while+ flag追加下次进入条件的方式写。
另外vector<int> out(26, 0)这种之类的写法很容易引起歧义所以会报错,用赋值的方法去替换。
五、二叉树题
1.翻转二叉树
class Solution { public: void invert(TreeNode* root){ if(root == nullptr) return; swap(root->left, root->right); invert(root->left); invert(root->right); } TreeNode* invertTree(TreeNode* root) { invert(root); return root; } };
2.对称二叉树
class Solution { public: bool checkSame(TreeNode* left, TreeNode* right){ if(left == nullptr && right == nullptr) return true; if(left == nullptr && right != nullptr) return false; if(left != nullptr && right == nullptr) return false; bool checkOutSide = checkSame(left->left, right->right); bool checkInside = checkSame(left->right, right->left); if(checkInside && checkOutSide && left->val == right->val) return true; return false; } bool isSymmetric(TreeNode* root) { return checkSame(root->left, root->right); } };
五.深度/广度优先搜索
1.岛屿数量 DFS版本
class Solution { public: int dx[4] = {-1, 0, 1, 0}; int dy[4] = {0, 1, 0, -1}; void color(vector<vector<char>>& grid, int x, int y, vector<vector<int>>& visited){ visited[x][y] = 1; for (int i = 0; i < 4; i++){ int newx = x + dx[i]; int newy = y + dy[i]; if (newx >= 0 && newy >= 0 && newx < grid.size() && newy < grid[0].size() && grid[newx][newy] == '1' && visited[newx][newy] == 0){ color(grid, newx, newy, visited); } } } int numIslands(vector<vector<char>>& grid) { int count = 0; vector<vector<int>> visited(grid.size(), vector<int>(grid[0].size(), 0)); for(int i = 0; i < grid.size(); i++){ for(int j = 0; j < grid[0].size(); j++){ if (grid[i][j] == '1' && visited[i][j] == 0){ count++; color(grid, i, j, visited); } } } return count; } };
2. 岛屿数量 BFS版本
class Solution { public: int dx[4] = {-1, 0, 1, 0}; int dy[4] = {0, 1, 0, -1}; vector<vector<int>> path; void bfs(vector<vector<char>>& grid, vector<vector<int>>& visited){ //cout << "path" << path.size() << endl; while(!path.empty()){ vector<int> incor = path.back(); path.pop_back(); int x = incor[0]; int y = incor[1]; cout << x << y << endl; for (int i = 0; i < 4; i++){ int newx = x + dx[i]; int newy = y + dy[i]; if (newx < 0 || newx >= grid.size() || newy < 0 || newy >= grid[0].size()) continue; if (grid[newx][newy] == '1' && visited[newx][newy] == 0){ path.push_back({newx, newy}); visited[newx][newy] = 1; } } } } int numIslands(vector<vector<char>>& grid) { int n = grid.size(); int m = grid[0].size(); vector<vector<int>> visited(n, vector<int>(m, 0)); //cout <<"enter" << endl; int count = 0; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ if (grid[i][j] == '1' && visited[i][j] == 0){ //cout <<"enter" << endl; count++; visited[i][j] = 1; path.push_back({i, j}); bfs(grid, visited); } } } return count; } };
3.岛屿最大面积(BFS)
class Solution { public: int dx[4] = {-1, 0, 1, 0}; int dy[4] = {0, 1, 0, -1}; vector<vector<int>> path; int bfs(vector<vector<int>>& grid, vector<vector<int>>& visited){ int n = grid.size(); int m = grid[0].size(); int count = 1; while(!path.empty()){ vector<int> cor = path.back(); path.pop_back(); int x = cor[0]; int y = cor[1]; for(int i = 0; i < 4; i++){ int newx = x + dx[i]; int newy = y + dy[i]; if (newx < 0 || newx >= n || newy < 0 || newy >= m) continue; if (grid[newx][newy] == 1 && visited[newx][newy] == 0){ visited[newx][newy] = 1; count++; path.push_back({newx, newy}); } } } return count; } int maxAreaOfIsland(vector<vector<int>>& grid) { int n = grid.size(); int m = grid[0].size(); int curCount; int historyMax = 0; vector<vector<int>> visited(n, vector<int>(m, 0)); for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ if(grid[i][j] == 1 && visited[i][j] == 0){ visited[i][j] = 1; path.push_back({i, j}); curCount = bfs(grid, visited); historyMax = max(curCount, historyMax); } } } return historyMax; } };
贪心算法
1.加油站(力扣134)
自己写法超时,附上自己的代码,每次判断剩余油量,不够就切到下一个,结果会超时。
class Solution { public: int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { vector<int> red(gas); for(int i = 0; i < red.size(); i++){ red[i] = gas[i] - cost[i]; } int st = -1; bool flag = true; //如果某一刻sum 小于0说明不足以到达下个点,则从本次起点的下一个点开始作为起点。 //如何统计跨边界的sum int size = red.size(); while(flag && st < size - 1){ flag = false; st = (st + 1) % red.size(); int loc = st; int sum = 0; while(loc <= red.size() - 1){ sum += red[loc]; loc++; if(sum < 0){ flag = true; break; } } if(flag) continue; loc = 0; while(loc < st){ sum += red[loc]; loc++; if(sum < 0){ flag = true; break; } } if(flag) continue; return st; } return -1; } };
代码随想录的答案的核心思想:tarSum表明如果无所谓过程中sum小不小于0,首先如果最后都是小于0的,一定跑不完一圈
但问题是最后大于0,起点未必是能从0开始的,可能0是最后一个点也说不好,所以提出一个过程中去统计的curSum,如果curSum小于0了,那么起点从i的下一个开始。
                
            
        
浙公网安备 33010602011771号