-
跟领导关系是否融洽
-
工作中有没有负面情绪
-
与团队关系怎么样
-
业务技能 (中上等 )
-
抗压能力
-
是否能按时完成工作任务
- hash map 自然去重,内存限制无法满足 (not ok)
- 排序 [解为多个文件然后用 合并排序或者桶排序],排序后可以方便的去重。(not ok)
- bitmap QQ号码为非负正整数且有最大值(类似桶排序),处理好后可直接作 去重 。
- 如果QQ号码均不相同 则可以作 top-K 排序使用。
- 可以借鉴MapReduce思想
- 采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,共需内存$2^{32}\times2=1G$内存,还可以接受。然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。所描完事后,查看bitmap,把对应位是01的整数输出即可。
- 进行划分小文件的方法。然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素.
- 取模 商趋向于 负无穷
- 取余 商趋向于 正无穷
- 排序后找到$Kth$值 Time:
$O(Nlog_2N)$ - 遍历数据同时放入小顶堆 Time:$O(Nlog_2K)$
- [快速选择] 类似 [快速排序] 能以最快$O(2N-1)$,[最差$O(N^2)$有序数组]速度找打$Kth$值 (e.g. 215)
- ###分布式服务器中较为准确的时间点
- 在MySQL中,当两个或两个以上的事务相互持有或者请求锁,并形成一个循环的依赖关系,就会产生死锁
- 两个或两个以上任务同时拥有并请求彼此的资源,请求时形成一个循环依赖关系,会产生死锁
- MySQL 的死锁检测算法是深度优先搜索等待关系图,如果在搜索过程中发现了环,就说明发生了死锁. 为了避免死锁检测开销过大,如果搜索深度超过了 200(LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK)也同样认为发生了死锁。[e.g. here]
- InnoDB 使用 MVCC 来解决事务的并发控制,而其中 Undo Log 是 MVCC 的重要组成部分
- 如何预防死锁
- 加锁顺序化。固定各个表的加锁顺序。
- 遇到可能的死锁不等待直接回滚事务。
- 事务开始前获取所有锁,或者等待执行。
- 在选项集合中遍历选项
- 做出选择
- 递归操作
- 撤销选择
- 回溯算法就是多叉树的遍历问题,关键是在前序遍历和后序遍历的位置做⼀些操作。某种程度上说,动态规划 的暴⼒求解阶段就是回溯算法。只是有的问题具有重叠⼦问题性质,可以⽤dp table或者备忘录优化,将递归树⼤幅剪枝,这就变成了动态规划。
- array
nums
of distinct integers, return all the possible permutations.46 Time$O(NN!)$ Space$O(NN!)$vector<vector<int>> permute(vector<int>& num) { vector<vector<int>> res; vector<int> out, visited(num.size(), 0); backtrack(num, 0, visited, out, res); return res; } void backtrack(vector<int>& num, int level, vector<int>& visited, vector<int>& out, vector<vector<int>>& res) { //level is recored current number of visited if (level == num.size()) { res.push_back(out); return; } for (int i = 0; i < num.size(); ++i) { if (visited[i] == 1) //position of num array continue; visited[i] = 1; out.push_back(num[i]); //make a choice backtrack(num, level + 1, visited, out, res); out.pop_back(); //cancel the choice visited[i] = 0; }//end for }
- array
nums
that mightcontain duplicates
integers, return all the possible permutations.47 Time$O(NN!)$ Space$O(NN!)$vector<vector<int>> permuteUnique(vector<int>& nums) { vector<vector<int>> res; vector<bool> visited(nums.size(),false); vector<int> out; sort(nums.begin(),nums.end()); bt(nums,res,out,visited,0); return res; } void bt(vector<int>& nums, vector<vector<int>>& res, vector<int>& out, vector<bool>& visi, size_t leve) { if(leve == nums.size()) { res.push_back(out); return; } for(size_t i=0; i<nums.size(); i++) { if(visi[i]) continue; //The relative position of the same elements in the arrangement remain unchanged if(i>0 && nums[i]==nums[i-1] && visi[i-1] == false) continue; visi[i] = true; out.push_back(nums[i]); bt(nums,res,out,visi,leve+1); out.pop_back(); visi[i] = false; } }
- integers
n
andk
, return all possible combinations ofk
numbers out of the range[1,n]
.77vector<vector<int>> combine(int n, int k) { vector<vector<int>> res; vector<int> out; backtrack(res,out,1,n,k);//start from 1, [1,....,n] return res; } //Have n select options(n width of decision tree), //k heigh of decision tree void backtrack(vector<vector<int>>&res ,vector<int>&out,int start, int n,int k) { if(static_cast<int>(out.size()) == k)//bottom of decision tree { res.push_back(out); return ; } for(int i=start; i<=n; i++) { out.push_back(i);//make a choice backtrack(res,out,i+1,n,k); out.pop_back(); } }//end backtrack;
- array of distinct integers candidates and a integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. The same number may be chosen from candidates an unlimited number of times.39
vector<vector<int>> combinationSum(vector<int>& candidates, int target) { vector<vector<int>> res; vector<int> out; bt(candidates,res,out,target,0,0); return res; } void bt(vector<int>& candidates, vector<vector<int>>& res, vector<int>& out, int target, int sum, int st) { if(sum == target) { res.push_back(out); return; } //Missing this condition will result in Time Limited Exceeded if(sum > target) return; for(int i=st; i<candidates.size(); i++) { sum += candidates[i]; out.push_back(candidates[i]); //The same number may be chosen from candidates an unlimited number of times. bt(candidates,res,out,target,sum,/*i+1*/ i); //Caution Here. out.pop_back(); sum -= candidates[i]; } }
- array of duplicated integers candidates and a integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. Each number in candidates may only be used once in the combination.40
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { vector<vector<int>> res; vector<int> out; std::sort(candidates.begin(),candidates.end()); //Sort this array bt(candidates,res,out,target,0,0); return res; } void bt(vector<int>& candidates, vector<vector<int>>& res, vector<int>& out, int target, int sum, std::size_t start) { if(sum == target) { res.push_back(out); return ; } //Missing this condition will result in Time Limit Exceeded if(sum > target) return ; for(std::size_t i=start; i<candidates.size(); i++) { //Remove duplicate elements if(i>start && candidates[i] == candidates[i-1]) continue; sum += candidates[i]; out.push_back(candidates[i]); bt(candidates,res,out,target,sum,i+1); out.pop_back(); sum -= candidates[i]; } }
- array nums of
distinct elements
, return all possible subsets (the power set).78 Time $O(N2^N)$ Space$O(N2^N)$vector<vector<int>> subsets(vector<int>& nums) { if(nums.size() <= 0) return vector<vector<int>>(); vector<vector<int>> res; vector<int> out; bt(nums,res,out,0); return res; } //end subsets void bt(vector<int>& nums,vector<vector<int>>& res,vector<int>& out,int start) { //this maybe a NULL set res.push_back(out); //start from empty subset for(int i=start; i<nums.size(); i++) { out.push_back(nums[i]); bt(nums,res,out,i+1); out.pop_back(); } }
- array nums that may
contain duplicates
, return all possible subsets (the power set).90vector<vector<int>> subsetsWithDup(vector<int>& nums) { std::vector<vector<int>> res; std::vector<int> out; std::sort(nums.begin(),nums.end());//sort array bt(nums,res,out,0); return res; } void bt(vector<int>& nums, vector<vector<int>>& res, vector<int>& out, size_t start) { res.push_back(out);//start from empty subset for(size_t i=start; i<nums.size(); i++) { //Preorder Position if(i>start && nums[i]==nums[i-1]) continue; out.push_back(nums[i]); bt(nums,res,out,i+1); out.pop_back(); //Postorder Position //while (i+1 < nums.size() && nums[i] == nums[i+1]) i++; } }
N-Queens
.51/* check is Queen valid at board[row][col]*/ bool isValid(vector<string>& board, int row, int col) { int n = board.size(); // check is same column /* no need to check row, because a row default is empty '.' */ for (int i = 0; i < n; i++) { if (board[i][col] == 'Q') return false; } // check upper right area for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) { if (board[i][j] == 'Q') return false; } // check upper left area for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { if (board[i][j] == 'Q') return false; } return true; }//end isValid vector<vector<string>> solveNQueens(int n) { vector<vector<string>> res; /* initialize board. '.' means empty, 'Q' means a Queen board contain n rows and n columns one row default is all empty '.' */ vector<string> board(n,string(n,'.')); backtrack(board,0,res); return res; } void backtrack(vector<string>& board,int row,vector<vector<string>>& res) { if(row == board.size()) { res.push_back(board); return ; } size_t numofCells1row = board[row].size(); for(size_t i=0;i<numofCells1row;i++) { if(!isValid(board,row,i)) continue; //make chance board[row].at(i) = 'Q'; //enter next row backtrack(board,row+1,res); //cancel the chance board[row].at(i) = '.'; } }//end backtrack
- 动态规划比较适合求解最优问题,最大值最小值等问题。我们把问题分解为多个阶段,每个阶段对应一个决策。我们记录每一个阶段可达的状态集合(去掉重复的),然后通过当前阶段的状态集合,来推导下一个阶段的状态集合,动态地往前推进。
- 普通二分查找
- 查第一个二分查找
- 查最后一个二分查找
- search normal
int Binary_normal(int*num,int tar,int lef ,int rig)
{
while(lef <= rig)
{
int mid = lef + (rig-lef)/2;//prevent overflow
if(num[mid] > tar)
rig = mid - 1;
else if(num[mid] < tar)
lef = mid + 1;
else
return mid;
}
return -1;
}
- search first
int Binary_first(int*num,int tar,int lef ,int rig) { while(lef <= rig) { int mid = lef + (rig-lef)/2; if(num[mid] > tar) rig = mid - 1; else if(num[mid] < tar) lef = mid + 1; else { //get the first when find equal elements if(mid==lef || num[mid-1]!=tar) return mid; rig = mid -1; } } return -1; }
- search last
int Binary_last(int*num,int tar,int lef ,int rig) { while(lef <= rig) { int mid = lef + (rig-lef)/2; if(num[mid] > tar) rig = mid - 1; else if(num[mid] < tar) lef = mid + 1; else { //get last when find equal elements if(mid==rig || num[mid+1]!=tar) return mid; lef = mid +1; } } return -1; }
- Unique BST.Integer
N
, return the number of unique BST's which has exactly n nodes of unique values from 1 toN
.96int numTrees(int n) { vector<vector<int>> // value from 1 to n ,so we need n+1 vector size dp(n+1,vector<int>(n+1,0));//dynamic programming去重备忘录 //it is arranged in order from 1 to n, which ensure a BST can be constructed return nums(1,n,dp); } int nums(int lft, int rgt,vector<vector<int>>& dp) { if(lft > rgt) return 1;//1 for multiply if(dp[lft][rgt] != 0) return dp[lft][rgt]; int res=0; for(int i=lft; i<=rgt; i++) { //i as root for this psuedo-subtree int left = nums(lft,i-1,dp); int right = nums(i+1,rgt,dp); res += left * right; //calculate them separately and add them } dp[lft][rgt] = res; //like post traversal tree return res; }
- Unique BST II.Integer
N
, return all unique BST's, which has exactlyn
nodes of unique values from1
toN
. 95vector<TreeNode*> generateTrees(int n) { return build(1,n); } vector<TreeNode*> build(int lft, int rgt) { if(lft>rgt) return {NULL};//for NULL node vector<TreeNode*> res; for(int i=lft; i<=rgt; i++) { vector<TreeNode*> left = build(lft,i-1); vector<TreeNode*> right = build(i+1,rgt); for(auto l:left) for(auto r:right) { TreeNode* root = new TreeNode(i);//i as root node of subtree root->left = l; root->right = r; res.push_back(root); } } return move(res);//like post order traversal }
- Maximum Binary Tree.Integer array
nums
with no duplicates. Return the maximum binary tree built fromnums
.654TreeNode* constructMaximumBinaryTree(vector<int>& nums) { TreeNode * root = helper(nums,0,static_cast<int>(nums.size())-1); return root; } TreeNode* helper(vector<int>& nums,int lft,int rgt) { if(lft > rgt) return NULL; int maxv=nums[lft], idx=lft; for (int i=lft; i<=rgt; i++) //find maximum value from lft to rgt { if(nums[i] > maxv) { maxv = nums[i]; idx = i; } } TreeNode * root = new TreeNode(maxv); root->left = helper(nums,lft,idx-1); root->right = helper(nums,idx+1,rgt); return root; }
Determine a binary tree is a valid binary search tree (BST).98
/* Subtree with node root as its root. min--> Subtree of node root's minimum value node max--> Subtree of node root's maximum value node */ bool preorder_traver(struct TreeNode* root,struct TreeNode* min,struct TreeNode* max) { if(root==NULL) return true; if(min && root->val <= min->val) return false; if(max && root->val >= max->val) return false; /* root as Left(root->left) subtree's maximum value node root as Right(root->right) subtree's minimum value node */ return preorder_traver(root->left,min,root) && preorder_traver(root->right,root,max); } bool isValidBST(struct TreeNode* root){ return preorder_traver(root,NULL,NULL); }
- Given a binary tree
root
, return the maximum sum of all keys of any sub-tree which is also a Binary Search Tree (BST).1373#define maxl(a,b)\ ({ __typeof__ (a) a_ = (a);\ __typeof__ (b) b_ = (b);\ a_ > b_ ? a_ : b_;}) struct context { bool isBST; int min; //minimum node of this tree(means this tree's minimum node) int max; //maximum node of this tree(means this tree's maximum node) int sum; //this tree's(if is a BST) sum of nodes }; struct context dfs(struct TreeNode* root,int *maxsum) { ////make sure a leaf is BST //this is a NULL pseudo-node,make sure its parent node(a leaf node) process condition // --> root->val > left.max && root->val < right.min if(root == NULL) { struct context temp = {true,40001,-40001,0}; return temp; } struct context left = dfs(root->left,maxsum); struct context right = dfs(root->right,maxsum); if(left.isBST==false || right.isBST==false || root->val <= left.max || root->val >= right.min) /*root->val > left.max and root->val < right.min is BST*/ { struct context temp = {false,0,0,0}; return temp; } struct context temp; temp.isBST = true; temp.min = (root->left ? left.min : root->val); //if has left subtree, set left subtre's min as total tree's minimum val temp.max = (root->right ? right.max : root->val); //if has right subtree, set right subtree's max as total tree's maximum val temp.sum = root->val + left.sum + right.sum; *maxsum = maxl(*maxsum,temp.sum); return temp; } //[4,3,null,1,2] int maxSumBST(struct TreeNode* root){ // Must initial a values or will get a wrong value // Example 3,All values are negatives. Return an empty BST. int maxSUm = 0; dfs(root,&maxSUm); return maxSUm; }
- Quick Sorts
//algorithm will cost 2 powers of N, when vector is increase or decrease template <typename T> void quick_sort1(T *a, int lft, int rgt) { if (lft >= rgt) return ;//caution this condition very import int i=lft ,j=rgt+1, pivot=a[lft]; while(1) { while(a[++i] < pivot) //skip the firt i(lft), because pivot is a[lft] if(i >= rgt) break; while (a[--j] > pivot) if(i <= lft) break; if(i < j) quicks_swap(a+i,a+j); else break; }//end while //swap pivot quicks_swap(a+j,a+lft);// Use j to swap pivot quick_sort1(a, lft, j-1); quick_sort1(a, j+1, rgt); } //algorithm will cost 2 powers of N, when vector is increase or decrease template <typename T> void quick_sort2(T *a, int lft, int rgt) { if (lft >= rgt) return ; //caution this condition very import int i=lft-1 ,j=rgt, pivot=a[rgt]; while(1) { while(a[++i] < pivot) if(i >= rgt) break; while (a[--j] > pivot) //skip the last j(rgt), because j is pivot if(i <= lft) break; if(i < j) quicks_swap(a+i,a+j); else break; }//end while //swap pivot quicks_swap(a+i,a+rgt); //Use i to swap pivot quick_sort2(a, lft, i-1); quick_sort2(a, i+1, rgt); }
- Merge Sort
template<class Iter> void mergeSort(Iter bgin, Iter end) //exclude iterator end. [bgin, end) { if( end - bgin <= 1 ) return ; Iter mid = bgin + (end-bgin)/2; mergeSort(bgin,mid); //[bgin,mid) mergeSort(mid,end); //[mid,end) std::inplace_merge(bgin,mid,end); /*Merges two consecutive sorted ranges: [first,middle) and [middle,last) putting the result into the combined sorted range [first,last).*/ }
138 Copy List with Random Pointer. 1、原链表节点追加新节点。--》 新节点random为原节点random的下一节点。 2、使用map存储 原节点为key ,新节点为value。
86 Partition List 1、按照x值将原链表分为两个子链表。--》将两个子链表合并为最终结果链表
148 Sort List
1、使用合并排序处理。使用到链表分裂功能
problems for 41,268,442,448,645
41 First Missing Positive
1、整数数组$nums$中将 元素下标$i$ 与 值$nums[i]$ 建立索引关系。($nums[i]-1 == i$ )
2、如果下标$i$与值$nums[i]$符合上述索引关系,则移动下标至下一个位置$i+1$。
3、否则 则将当前下标$i$处元素 与 下标$nums[i]-1$处元素交换值。直到符合上述索引关系后 再移动索引至下一位置。
int firstMissingPositive(int* nums, int numsSize){ for(int i=0; i<numsSize;) { if(nums[i]>0 && nums[i]-1 != i && nums[i]-1 < numsSize /*prevent array overflow*/ && nums[i] != nums[nums[i]-1]/*remove duplicate element, prevent infinite loop*/){ std::swap(nums+i,nums+nums[i]-1); }else ++i; } //check the result for(int i=0; i<numsSize;i++){ if(nums[i]!= i+1 /*[-2147483648] over flow*/) { return i+1; } } return numsSize+1; }