1.Flatten Binary Tree to Linked List
1 //dfs、前序遍历一下即可 2 class Solution { 3 public: 4 void dfs(TreeNode* root, TreeNode* &pre) 5 { 6 if (root == NULL) return ; 7 pre->left = root; 8 pre = pre->left; 9 if (root->left) dfs(root->left, pre); 10 if (root->right) dfs(root->right, pre); 11 } 12 void work(TreeNode *root) 13 { 14 if (root == NULL) return; 15 if (root->left) work(root->left); 16 root->left = NULL; 17 } 18 void flatten(TreeNode* root) { 19 if (root == NULL) return ; 20 TreeNode* tmp = new TreeNode(-1); 21 dfs(root, tmp); 22 TreeNode *t = root; 23 while (t) 24 { 25 t->right = t->left; 26 t = t->left; 27 } 28 t = root; 29 work(t); 30 } 31 };
2.Convert Sorted List to Binary Search Tree
1 //递归,根据postorder来做,postorder最后一个值肯定是root,根据这个来做即可。 2 class Solution { 3 public: 4 TreeNode* build(vector<int>& inorder, vector<int>& postorder, int left1, int right1, int left2, int right2) 5 { 6 if (left1 > right1) return NULL; 7 TreeNode *tmp = new TreeNode(postorder[right2]); 8 if (left1 == right1) 9 return tmp; 10 int i, j; 11 for (i = right1; i >= left1; --i) 12 if (inorder[i] == postorder[right2]) break; 13 tmp->right = build(inorder, postorder, i+1, right1, right2-1-(right1-i-1), right2-1); 14 tmp->left = build(inorder, postorder, left1, i-1, left2, right2-1-(right1-i-1)-1); 15 } 16 17 TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { 18 return build(inorder, postorder, 0, inorder.size()-1, 0, postorder.size()-1); 19 } 20 };
3. 三个随机输入的数组,输出同时在3个数组中都存在的数字(qunar笔试)
1 //排序 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <string> 7 #include <cstring> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <stack> 12 #include <queue> 13 14 using namespace std; 15 16 int main() 17 { 18 int n[3]; 19 vector<int> v[3]; 20 21 for (int i = 0; i < 3; ++i) 22 { 23 int val; 24 scanf("%d", &n[i]); 25 for (int j = 0; j < n[i]; ++j) 26 { 27 scanf("%d", &val); 28 v[i].push_back(val); 29 } 30 sort(v[i].begin(), v[i].end()); 31 } 32 33 int l0 = 0, l1 = 0, l2 = 0, flag = 0; 34 int r0 = v[0].size(), r1 = v[1].size(), r2 = v[2].size(); 35 while (true) 36 { 37 if (v[0][l0] == v[1][l1] && v[2][l2] == v[1][l1]) 38 { 39 if (flag) printf(" "); 40 printf("%d", v[0][l0]); 41 flag = 1; 42 l0++, l1++, l2++; 43 continue; 44 } 45 int val = min(min(v[0][l0], v[1][l1]), v[2][l2]); 46 if (val == v[0][l0]) l0++; 47 if (val == v[1][l1]) l1++; 48 if (val == v[2][l2]) l2++; 49 if (l0 == r0 || l1 == r1 || l2 == r2) break; 50 } 51 52 return 0; 53 }
1 //n^3复杂度,利用map解决 2 class Solution 3 { 4 public: 5 /** 6 * @param matrix an integer matrix 7 * @return the coordinate of the left-up and right-down number 8 */ 9 vector<vector<int>> submatrixSum(vector<vector<int>>& matrix) 10 { 11 vector<vector<int>> ans; 12 int m = matrix.size(); 13 if (m == 0) return ans; 14 int n = matrix[0].size(); 15 if (m == 0) return ans; 16 17 vector<int> t(n+1, 0); 18 vector<vector<int>> dp(m+1, t); 19 20 for (int i = 0; i < m; ++i) 21 for (int j = 0; j < n; ++j) 22 dp[i+1][j+1] = matrix[i][j] + dp[i+1][j] + dp[i][j+1] - dp[i][j]; 23 24 for (int l = 0; l < m; ++l) 25 { 26 for (int h = l+1; h <= m; ++h) 27 { 28 map<int, int> mp; 29 for (int j = 0; j <= n; ++j) 30 { 31 int diff = dp[h][j] - dp[l][j]; 32 if (mp.count(diff)) 33 { 34 int k = mp[diff]; 35 vector<int> add; 36 add.push_back(l), add.push_back(k); 37 ans.push_back(add); add.clear(); 38 add.push_back(h-1), add.push_back(j-1); 39 ans.push_back(add); 40 return ans; 41 } 42 else mp.insert(make_pair(diff, j)); 43 } 44 } 45 } 46 return ans; 47 } 48 };
1 //统计数字的二进制里有多少个1即可 2 #include <iostream> 3 #include <algorithm> 4 #include <string> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <queue> 8 #include <list> 9 #include <vector> 10 #include <map> 11 #include <set> 12 13 using namespace std; 14 15 int main() 16 { 17 int n, ans = 0; 18 scanf("%d", &n); 19 for (int i = 0; i < 32; ++i) 20 { 21 ans += n&1; 22 n >>= 1; 23 } 24 printf("%d ", ans); 25 26 return 0; 27 }
6.Pet
1 //BFS 2 #include <iostream> 3 #include <algorithm> 4 #include <string> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <queue> 8 #include <list> 9 #include <vector> 10 #include <map> 11 #include <set> 12 13 using namespace std; 14 15 const int maxn = 100010; 16 int vis[maxn]; 17 int t, n, d; 18 vector<int> v[maxn]; 19 20 int main() 21 { 22 int x, y; 23 24 scanf("%d", &t); 25 while (t--) 26 { 27 for (int i = 0; i < maxn; ++i) 28 vis[i] = 0, v[i].clear(); 29 scanf("%d%d", &n, &d); 30 for (int i = 1; i < n; ++i) 31 { 32 scanf("%d%d", &x, &y); 33 v[x].push_back(y); 34 } 35 queue<pair<int, int>> qu; 36 qu.push(make_pair(0, 0)); 37 while (!qu.empty()) 38 { 39 int val = qu.front().first; 40 int dep = qu.front().second; 41 qu.pop(); 42 if (dep > d) break; 43 vis[val] = 1; 44 for (int i = 0; i < v[val].size(); ++i) 45 { 46 if (vis[v[val][i]]) continue; 47 qu.push(make_pair(v[val][i], dep+1)); 48 } 49 } 50 int ans = 0; 51 for (int i = 0; i < n; ++i) 52 ans += vis[i] ? 0 : 1; 53 printf("%d ", ans); 54 } 55 56 return 0; 57 }
1 //sort pair 2 #include <iostream> 3 #include <string> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <algorithm> 11 12 using namespace std; 13 14 const int maxn = 810; 15 int n; 16 int vis[maxn]; 17 18 int main() 19 { 20 int tmp; 21 scanf("%d", &n); 22 vector<pair<int, pair<int, int> > > v; 23 for (int i = 2; i <= 2*n; ++i) 24 { 25 for (int j = 1; j < i; ++j) 26 { 27 cin >> tmp; 28 v.push_back({tmp, {i, j}}); 29 } 30 } 31 memset(vis, 0, sizeof(vis)); 32 sort(v.begin(), v.end()); 33 reverse(v.begin(), v.end()); 34 for (int i = 0; i < v.size(); ++i) 35 { 36 if (!vis[v[i].second.first] && !vis[v[i].second.second]) 37 { 38 vis[v[i].second.first] = v[i].second.second; 39 vis[v[i].second.second] = v[i].second.first; 40 } 41 } 42 for (int i = 1; i <= 2*n; ++i) 43 { 44 if (i != 1) printf(" "); 45 printf("%d", vis[i]); 46 } 47 puts(""); 48 49 return 0; 50 }
1 //状态压缩基础题 2 #include <iostream> 3 #include <string> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 #include <vector> 9 #include <queue> 10 #include <map> 11 #include <set> 12 13 using namespace std; 14 15 const int mod = 100000000; 16 int m, n; 17 int a[13]; 18 int dp[15][(1<<12)+10]; 19 20 bool check(int x, int y) 21 { 22 if ((a[x]&y) != y) return false; 23 if ((y&(y<<1)) != 0 || (y&(y>>1)) != 0) return false; 24 return true; 25 } 26 27 void work() 28 { 29 int mnum; 30 memset(dp, 0, sizeof(dp)); 31 dp[0][0] = 1; 32 mnum = 1<<n; 33 for (int i = 1; i <= m; ++i) 34 { 35 for (int j = 0; j < mnum; ++j) 36 { 37 if (!check(i, j)) continue; 38 for (int k = 0; k < mnum; ++k) 39 { 40 if ((j&k) != 0) continue; 41 dp[i][j] += dp[i-1][k]; 42 dp[i][j] %= mod; 43 } 44 } 45 } 46 int ans = 0; 47 for (int i = 0; i < mnum; ++i) 48 { 49 ans += dp[m][i]; 50 ans %= mod; 51 } 52 printf("%d ", ans); 53 } 54 55 int main() 56 { 57 int val; 58 while (~scanf("%d%d", &m, &n)) 59 { 60 for (int i = 1; i <= m; ++i) 61 { 62 a[i] = 0; 63 for (int j = 1; j <= n; ++j) 64 { 65 scanf("%d", &val); 66 a[i] = (a[i]<<1)+val; 67 } 68 } 69 work(); 70 } 71 72 return 0; 73 }
9.炮兵阵地
1 //经典状态DP题, 开一个数组保存状态 2 //【状态表示】dp[i][j][k] 表示第i行状态为k,第i-1状态为j时的最大炮兵个数。 3 //【状态转移方程】dp[i][k][t] =max(dp[i][k][t],dp[i-1][j][k]+num[t]); num[t]为t状态中1的个数 4 //【DP边界条件】dp[1][0][i] =num[i] 状态i能够满足第一行的硬件条件(注意:这里的i指的是第i个状态,不是一个二进制数,开一个数组保存二进制状态) 5 #include <iostream> 6 #include <string> 7 #include <cstdlib> 8 #include <cstdio> 9 #include <cstring> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <map> 14 #include <set> 15 16 using namespace std; 17 18 int dp[105][100][100]; 19 int g[105]; 20 int v[100]; 21 int num[105]; 22 int n, m, top; 23 24 bool check(int x) 25 { 26 if ((x&(x>>1)) != 0) return 0; 27 if ((x&(x>>2)) != 0) return 0; 28 if ((x&(x<<1)) != 0) return 0; 29 if ((x&(x<<2)) != 0) return 0; 30 return 1; 31 } 32 33 void init() 34 { 35 memset(dp, -1, sizeof(dp)); 36 top = 0; 37 int total = 1<<m; 38 for (int i = 0 ; i < total; ++i) 39 if (check(i)) v[top++] = i; 40 } 41 42 bool fit(int x, int y) 43 { 44 if ((g[y]&x) != x) return false; 45 return true; 46 } 47 48 int get1(int val) 49 { 50 int ans = 0; 51 while (val) 52 { 53 ans += (val&1); 54 val >>= 1; 55 } 56 return ans; 57 } 58 59 void work() 60 { 61 for (int i = 0; i < top; ++i) 62 { 63 num[i] = get1(v[i]); 64 if (fit(v[i], 1)) dp[1][0][i] = num[i]; 65 } 66 67 for (int i = 2; i <= n; ++i) 68 { 69 for (int t = 0; t < top; ++t) 70 { 71 if (!fit(v[t], i)) continue; 72 for (int j = 0; j < top; ++j) 73 { 74 if (v[t]&v[j]) continue; 75 for (int k = 0; k < top; ++k) 76 { 77 if (v[k]&v[t]) continue; 78 if (dp[i-1][j][k] == -1) continue; 79 dp[i][k][t] = max(dp[i][k][t], dp[i-1][j][k]+num[t]); 80 } 81 } 82 } 83 } 84 85 int ans = 0; 86 for (int i = 1; i <= n; ++i) 87 for (int j = 0; j < top; ++j) 88 for (int k = 0; k < top; ++k) 89 ans = max(ans, dp[i][j][k]); 90 printf("%d ", ans); 91 } 92 93 int main() 94 { 95 char c; 96 while (~scanf("%d%d", &n, &m) && (m+n)) 97 { 98 getchar(); 99 for (int i = 1; i <= n; ++i) 100 { 101 g[i] = 0; 102 for (int j = 1; j <= m; ++j) 103 { 104 scanf("%c", &c); 105 if (c == 'P') g[i] = (g[i]<<1)+1; 106 else g[i] = (g[i]<<1)+0; 107 } 108 getchar(); 109 } 110 init(); 111 work(); 112 } 113 114 115 return 0; 116 }
1 //这题算啥,直接暴力不行,反正是瞎搞的 2 class Solution { 3 public: 4 int height(TreeNode *root) 5 { 6 if (root == NULL) return 0; 7 return 1+height(root->left); 8 } 9 10 int work(TreeNode *root, int val) 11 { 12 if (root == NULL) return val; 13 if (height(root->left) == height(root->right)) 14 { 15 if (root->right == NULL) return val; 16 return (val/2)+work(root->right, val/2); 17 } 18 if (root->left == NULL) return val; 19 else return work(root->left, val/2); 20 } 21 22 int countNodes(TreeNode* root) { 23 if (root == NULL) return 0; 24 int depth = height(root); 25 int val = pow(2, depth-1); 26 int ans = pow(2, depth-1)-1; 27 return work(root, val)+ans; 28 } 29 };
1 //状态转移方程 dp[s][i] =min{dp[s][i],dp[s'][j]+dis[j][i]} dp[s][i]表示到达状态s时位于i位置的最小耗费,dis[j][i]表示两点之间的最短路.在DP之前要用floyd预处理一下求//出每两个点之间的最短距离。 2 #include <iostream> 3 #include <string> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 #include <vector> 9 #include <queue> 10 #include <map> 11 #include <set> 12 13 #define INT_MAX 2147483647 14 using namespace std; 15 16 const int maxn = 11; 17 18 int g[maxn][maxn]; 19 int dp[1<<10+10][maxn]; 20 int n; 21 22 void floyd() 23 { 24 for (int i = 0; i <= n; ++i) 25 for (int j = 0; j <= n; ++j) 26 for (int k = 0; k <= n; ++k) 27 if (g[i][j] > g[i][k]+g[k][j]) 28 g[i][j] = g[i][k]+g[k][j]; 29 } 30 31 void work() 32 { 33 int m = (1<<n); 34 35 for (int s = 0; s < m; ++s) 36 { 37 for (int i = 1; i <= n; ++i) 38 { 39 if (s&(1<<(i-1))) 40 { 41 if (s == (1<<(i-1))) 42 dp[s][i] = g[0][i]; 43 else 44 { 45 dp[s][i] = INT_MAX; 46 for (int j = 1; j <= n; ++j) 47 { 48 if (s&(1<<(j-1)) && j != i) 49 dp[s][i] = min(dp[s][i], dp[s^(1<<(i-1))][j]+g[j][i]); 50 } 51 } 52 } 53 } 54 } 55 int ans = dp[m-1][1]+g[1][0]; 56 for (int i = 2; i <= n; ++i) 57 ans = min(ans, dp[m-1][i]+g[i][0]); 58 printf("%d ", ans); 59 } 60 61 int main() 62 { 63 while (~scanf("%d", &n) && n) 64 { 65 66 for (int i = 0; i <= n; ++i) 67 for (int j = 0; j <= n; ++j) 68 scanf("%d", &g[i][j]); 69 floyd(); 70 work(); 71 } 72 73 return 0; 74 }
12.Different Ways to Add Parenthese
1 //分治 2 class Solution { 3 public: 4 vector<int> work(vector<pair<int, int>>& vec, int left, int right) 5 { 6 vector<int> v1, v2, v3; 7 if (left == right) 8 { 9 v3.push_back(vec[left].first); 10 return v3; 11 } 12 for (int i = left; i <= right; ++i) 13 { 14 if (vec[i].second) 15 { 16 int flag = vec[i].first; 17 v1 = work(vec, left, i-1); 18 v2 = work(vec, i+1, right); 19 for (int j = 0; j < v1.size(); ++j) 20 { 21 for (int k = 0; k < v2.size(); ++k) 22 { 23 int t1 = v1[j], t2 = v2[k]; 24 if (flag == 1) v3.push_back(t1+t2); 25 else if (flag == 2) v3.push_back(t1-t2); 26 else if (flag == 3) v3.push_back(t1*t2); 27 } 28 } 29 } 30 } 31 return v3; 32 } 33 34 vector<int> diffWaysToCompute(string input) { 35 vector<pair<int, int>> vec; 36 int tmp = 0; 37 for (int i = 0; i < input.length(); ++i) 38 { 39 if (input[i] == '+') 40 { 41 vec.push_back({tmp, 0}); 42 tmp = 0; 43 vec.push_back({1, 1}); 44 } 45 else if (input[i] == '-') 46 { 47 vec.push_back({tmp, 0}); 48 tmp = 0; 49 vec.push_back({2, 1}); 50 } 51 else if (input[i] == '*') 52 { 53 vec.push_back({tmp, 0}); 54 tmp = 0; 55 vec.push_back({3, 1}); 56 } 57 else tmp = tmp*10 + input[i]-'0'; 58 if (i == input.length()-1) vec.push_back({tmp, 0}); 59 } 60 vector<int> ans; 61 ans= work(vec, 0, vec.size()-1); 62 sort(ans.begin(), ans.end()); 63 return ans; 64 } 65 };
1 //DFS, 注意'0' 2 class Solution { 3 public: 4 vector<string> addOperators(string num, int target) { 5 vector<string> res; 6 addOperatorsDFS(num, target, 0, 0, "", res); 7 return res; 8 } 9 void addOperatorsDFS(string num, int target, long long diff, long long curNum, string out, vector<string> &res) { 10 if (num.size() == 0 && curNum == target) { 11 res.push_back(out); 12 } 13 for (int i = 1; i <= num.size(); ++i) { 14 string cur = num.substr(0, i); 15 if (cur.size() > 1 && cur[0] == '0') return; 16 string next = num.substr(i); 17 if (out.size() > 0) { 18 addOperatorsDFS(next, target, stoll(cur), curNum + stoll(cur), out + "+" + cur, res); 19 addOperatorsDFS(next, target, -stoll(cur), curNum - stoll(cur), out + "-" + cur, res); 20 addOperatorsDFS(next, target, diff * stoll(cur), (curNum - diff) + diff * stoll(cur), out + "*" + cur, res); 21 } else { 22 addOperatorsDFS(next, target, stoll(cur), stoll(cur), cur, res); 23 } 24 } 25 } 26 };
14.Kth Largest Element in an Array
1 //priority queue 2 class Solution { 3 public: 4 int findKthLargest(vector<int>& nums, int k) { 5 priority_queue<int> qu; 6 for (int i = 0; i < nums.size(); ++i) 7 qu.push(nums[i]); 8 for (int i = 0; i < k-1; ++i) 9 qu.pop(); 10 return qu.top(); 11 } 12 };
15. 滴滴打车笔试题
(超水的题目,替别人做的)给出多个数字输入,寻找最长的连续和为0的序列,并输出。
例如:input 1 -1 1 -1 2 -2 3 1 -1 -2 2
output : 1 -1 1 -1 2 -2
复杂度O(n),扫描一遍即可
1 #include <iostream> 2 #include <string> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #include <vector> 8 #include <queue> 9 #include <map> 10 #include <set> 11 #include <priority_queue> 12 #include <unordered_map> 13 #include <unordered_set> 14 15 #define INT_MAX 2147483647 16 using namespace std; 17 18 int main() 19 { 20 vector<int> v1, v2; 21 unordered_map<int, int> mp; 22 int val; 23 int left, right; 24 25 while (~scanf("%d", &val)) v1.push_back(val), v2.push_back(val); 26 27 val = 0; 28 for (int i = 1; i < v1.size(); ++i) 29 { 30 v1[i] += v1[i-1]; 31 if (v1[i] == 0 && (i+1) > val) val = i+1, left = 0, right = i; 32 if (mp.count(v1[i]) == 0) mp.insert({v1[i], i}); 33 else 34 { 35 if (i-mp[v1[i]] > val) val = i-mp[v1[i]], left = mp[v1[i]]+1, right = i; 36 } 37 } 38 39 for (int i = left; i <= right; ++i) 40 { 41 if (i != left) printf(" "); 42 printf("%d", v2[i]); 43 } 44 puts(""); 45 46 return 0; 47 }
总结:这周主要做了一下DP类的题目,状态压缩DP,但是感觉DP类的题目还是不咋会做。看了几篇论文,也算是有点收获。中秋节,好好过节~~~~~~~~
下周:网络流类题目至少做10道。 论文至少3篇。以后每周做一个类型的就可以,没啥事刷刷leetcode lintcode,如果乱做题,感觉收获不大。加油~
//计划不如变化快,尽量按照计划来!