楼主: 大木虫
跳转到指定楼层
上一主题 下一主题
收起左侧

Elements of Programming Interviews 白班编程记录,求挑刺求反馈

 
🔗
 楼主| 大木虫 2018-12-10 05:43:23 | 只看该作者
全局:
399. Evaluate Division

第三遍写这道题,用时21分钟,有3个syntax error和1个sematic error
花了8分钟修改错误,然后AC

syntax error:
1. 在应该assign的地方写了return
2. unordered_map passed by const reference的时候不能用[ ]访问,要用iterator访问(map[key]->second)
3. double 写错成了 string

semantic error:
1. 在查querie的时候遇到from == dst的case时没有检查from是否存在于图中,如果不存在的话,应该返回-1,但是我的程序忘记检查这一项,返回了1,是错的。

延伸:
还有union find的解,但是我对union find不是很熟练,所以不想写了。我知道这样不对,但是我就是做不到现在花时间研究union find解法,因为目前意志力不够强。
不过我要在看一遍union find的视频,掌握其思路。

  1. class Solution {
  2. public:
  3.     vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
  4.         /* 0.MISC */
  5.         
  6.         /* 1. prep */
  7.         vector<double> answer;
  8.         auto graph = BuildGraph(equations, values);
  9.         
  10.         /* 2. key algo */
  11.         for(auto query: queries){
  12.             string from = query.first, dst = query.second;
  13.             double ansElement = 1.0;
  14.             
  15.             if(from == dst && graph.find(from) != graph.end())ansElement = 1.0;
  16.             else if(graph.find(from) == graph.end() || graph.find(dst) == graph.end())ansElement = -1.0;
  17.             else{
  18.                 double ratio = RatioBFS(graph, from, dst);
  19.                 ansElement = ratio;
  20.             }
  21.             
  22.             answer.emplace_back(ansElement);
  23.         }
  24.         
  25.         /* 3. answer */
  26.         return answer;
  27.     }   
  28.    
  29.     double
  30.     RatioBFS(const unordered_map<string, vector< pair<string, double> > > & graph,
  31.              const string& from, const string& dst){
  32.         /* 0. MISC */
  33.         
  34.         /* 1. prep */
  35.         queue<pair<string, double> > bfsQueue;
  36.         unordered_set<string> visited;
  37.         
  38.         bfsQueue.emplace(from, 1.0);
  39.         visited.emplace(from);
  40.         
  41.         /* 2. key algo */
  42.         while(!bfsQueue.empty()){
  43.             auto node = bfsQueue.front(); bfsQueue.pop();
  44.             auto nodeName = node.first;
  45.             auto nodeRatio = node.second;
  46.             
  47.             for(auto child: graph.find(nodeName)->second){
  48.                 string childName = child.first;
  49.                 double relativeRatio = child.second;
  50.                
  51.                 if(visited.find(childName) != visited.end())continue;
  52.                 visited.emplace(childName);
  53.                
  54.                 double childRatio = nodeRatio * relativeRatio;
  55.                 if(childName == dst)return childRatio;
  56.                
  57.                 bfsQueue.emplace(childName, childRatio);               
  58.             }            
  59.         }
  60.         
  61.         /* 3. answer */
  62.         return -1;
  63.     }
  64.    
  65.     unordered_map<string, vector< pair<string, double> > >
  66.     BuildGraph( const vector<pair<string, string>> equations,
  67.                 const vector<double>& values){
  68.         /* 0. MISC */
  69.         
  70.         /* 1. prep */
  71.         unordered_map<string, vector< pair<string, double> > > graph;
  72.         
  73.         /* 2. key algo */
  74.         for(int i = 0; i < equations.size(); ++i){
  75.             string from = equations[i].first, dst = equations[i].second;
  76.             double ratio = values[i];
  77.             graph[from].emplace_back(dst, ratio);
  78.             graph[dst].emplace_back(from, 1/ratio);
  79.         }
  80.         
  81.         /* 3. answer */
  82.         return graph;
  83.         
  84.     }
  85. };
复制代码

补充内容 (2018-12-10 05:45):
如果是上白板写这道题,85行代码还是太长,需要舍弃一些。我是这样安排的,先写最核心的BFS部分,再写query的部分,最后写BuildGraph.
回复

使用道具 举报

🔗
wocaole 2018-12-10 06:57:22 | 只看该作者
全局:
这个不错。向您学习。
回复

使用道具 举报

🔗
 楼主| 大木虫 2018-12-10 12:49:55 | 只看该作者
全局:
684. Redundant Connection
第二遍写,没有写出来。明天早上写。
回复

使用道具 举报

🔗
 楼主| 大木虫 2018-12-11 06:28:36 | 只看该作者
全局:
684. Redundant Connection

15分钟AC

昨天犯了几个错误,第一,找环如果想要拎出一个方向一致的环,那就要用DFS而不是BFS。第二,mark visited要在pop之后,而不是在child discovery的时候,因为后者会造成trace back 分叉,使环的方向不一致,拎的时候很麻烦。

  1. class Solution {
  2. public:
  3.     vector<int> findRedundantConnection(vector<vector<int>>& edges) {
  4.         /* 0. MISC */
  5.         
  6.         /* 1. prep */
  7.         auto graph = BuildGraph(edges);
  8.         stack<int> dfsStack;
  9.         vector<bool> visited(edges.size() + 1, false);
  10.         vector<int> traceBack(edges.size() + 1, -1);
  11.         unordered_set<string> cycleEdges;
  12.         
  13.         dfsStack.emplace(1);
  14.         
  15.         /* 2. key algo */
  16.         while(!dfsStack.empty()){
  17.             int node = dfsStack.top(); dfsStack.pop();
  18.             visited[node] = true;
  19.             
  20.             for(int child: graph[node]){
  21.                 if(visited[child] == false){
  22.                     traceBack[child] = node;
  23.                     dfsStack.emplace(child);
  24.                 }else if(child != traceBack[node]){
  25.                     int dest = child;
  26.                     string startEdge = Encode({node, dest});
  27.                     cycleEdges.emplace(startEdge);
  28.                     
  29.                     int current = node;
  30.                     while(current != dest){
  31.                         int next = traceBack[current];
  32.                         cycleEdges.emplace(Encode({current, next}));
  33.                         current = next;
  34.                     }
  35.                     
  36.                     for(int i = edges.size() - 1; i >= 0; --i){
  37.                         string edgeStr = Encode(edges[i]);
  38.                         if(cycleEdges.find(edgeStr) != cycleEdges.end()){
  39.                             return edges[i];
  40.                         }
  41.                     }
  42.                 }
  43.             }
  44.             
  45.         }
  46.         
  47.         /* 3. answer */
  48.         return {-1, -1}; /* handle err case */
  49.     }
  50.    
  51.     string Encode(const vector<int>& edge){
  52.         return to_string(min(edge[0], edge[1])) + " " + to_string(max(edge[0], edge[1]));
  53.     }
  54.    
  55.     vector<vector<int>> BuildGraph(const vector<vector<int>>& edges){
  56.         /* 0. MISC */
  57.         
  58.         /* 1. prep */
  59.         vector<vector<int>> graph(edges.size() + 1, vector<int>());
  60.         
  61.         /* 2. key algo */
  62.         for(auto edge: edges){
  63.             graph[edge[0]].emplace_back(edge[1]);
  64.             graph[edge[1]].emplace_back(edge[0]);
  65.         }
  66.         
  67.         /* 3. answer */
  68.         return graph;
  69.     }
  70.    
  71. };
复制代码
回复

使用道具 举报

🔗
 楼主| 大木虫 2018-12-13 00:40:58 | 只看该作者
全局:
LC 312. Burst Balloons

经典DP题目,backtracking + DP + memo,28分钟AC
核心要点是找到正确的拓扑图,正确的拓扑图的branching factor比较低。
找到正确拓扑图的要点是按照题目逻辑从多个方向想解,这里的运用是从正向想解和反向想解。

正向拓扑图这里的branch factor很大(n)因为每扎一个气球都会影响之后的sub problem,所以每次都要重新构建,sub problem无法得到有效重复利用
反向拓扑图则成功地把branch factor减小到2,因为后扎的气球无法影响到前扎的气球,所以sub problem不会受main problem的影响(无后效性),因此只要逻辑上保证sub problem可以构建最优解,sub problem就可以被重复利用达到提速的目的。

  1. class Solution {
  2. public:
  3.     int maxCoins(vector<int>& nums) {
  4.         /* 0. MISC */
  5.         if(nums.empty())return 0;
  6.         
  7.         /* 1. prep */
  8.         vector<vector<int>> dpMatrix(nums.size(), vector<int>(nums.size(), -1));
  9.         
  10.         /* 2. key algo */
  11.         MaxCoinsRec(nums, 0, nums.size() - 1, 1, 1, dpMatrix);
  12.         
  13.         /* 3. answer */
  14.         return dpMatrix[0][nums.size() - 1];
  15.     }
  16.    
  17.     int MaxCoinsRec(const vector<int>& nums, int start, int last, int leftSide, int rightSide, vector<vector<int>>& dpMatrix){
  18.         /* 0. MISC */
  19.         if(start > last)return 0; /* empty case */
  20.         if(dpMatrix[start][last] != -1)return dpMatrix[start][last];
  21.         
  22.         /* 1. prep */
  23.         int maxAns = 0;
  24.         
  25.         /* 2. key algo */
  26.         for(int i = start; i <= last; ++i){
  27.             int curAns =
  28.                 nums[i] * leftSide * rightSide +
  29.                 MaxCoinsRec(nums, start, i - 1, leftSide, nums[i], dpMatrix) +
  30.                 MaxCoinsRec(nums, i + 1, last, nums[i], rightSide, dpMatrix);
  31.             
  32.             maxAns = max(maxAns, curAns);
  33.         }
  34.         
  35.         /* 3. answer */
  36.         dpMatrix[start][last] = maxAns;
  37.         return maxAns;
  38.     }   
  39.    
  40. };
复制代码
回复

使用道具 举报

🔗
totolin 2018-12-18 00:57:05 | 只看该作者
全局:
楼主加油啊~~
回复

使用道具 举报

全局:
请问楼主这是什么语言啊
回复

使用道具 举报

🔗
R.F 2019-2-7 22:24:32 | 只看该作者
全局:
楼主很厉害,谢谢分享。楼主在白板写完以后还会敲代码到计算机里面去运行么?
回复

使用道具 举报

🔗
yolanda杨杨 2019-2-13 06:04:07 | 只看该作者
全局:
喜欢lz这种高质量的刷题方式,感觉我自己也要反省一下,自己一直很介意刷题量上不去其实没有必要,重要的是把刷过的题目搞明白。
回复

使用道具 举报

全局:
刚拿到offer 9月开学的表示:我是商科转码,修过必修课但课程太水没啥子用,适用EPI吗?如果不适合,建议做什么较佳呢?谢谢各位!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表