Palindrome Pairs

warm up:is_palindrome

bool isPalindrome(string s) {int left = 0, right = s.size() - 1;while (left < right) {if (s[left++] != s[right--]) return false;}return true;
}

给定一个字符串数组,找出所有的字符串对,该字符串对拼接起来是回文字符串(https://leetcode.com/problems/palindrome-pairs/?tab=Description)

#include <iostream>
#include <unordered_map>
#include <set>
#include <vector>
using namespace std;bool isPalindrome(string word, int left, int right) {while (left < right)if(word[left++] != word[right--]) return false;return true;
}vector<vector<int> > palindromePairs(vector<string>& words) {unordered_map<string, int> idx;set<int> st;vector<vector<int> > ans;for (int i = 0; i < words.size(); ++i) {idx[words[i]] = i;st.insert(words[i].length());}for (int i = 0 ; i < words.size(); ++i) {string tmp = words[i];int len = tmp.length();reverse(tmp.begin(), tmp.end());if (idx.count(tmp) && idx[tmp] != i)ans.push_back({i, idx[tmp]});auto end = st.find(len);for (auto it = st.begin(); it != end; ++it) {if (idx.count(tmp.substr(len - *it)) && isPalindrome(tmp, 0, len - *it - 1))ans.push_back({i, idx[tmp.substr(len - *it)]});if (idx.count(tmp.substr(0, *it)) && isPalindrome(tmp, *it, len - 1))ans.push_back({idx[tmp.substr(0, *it)], i});}}return ans;
}
int main() {vector<string> words = {"bat", "tab", "cat"};auto ans = palindromePairs(words);for (auto pr : ans) {cout << pr[0] << " "<< pr[1] <<endl;}return 0;
}

Round numbers

When you book on airbnb the total price is:

Total price = base price + service fee + cleaning fee + …

input : array of decimals ~ X
output : array of int ~ Y

But they need to satisfy the condition:

sum(Y) = round(sum(x))
minmize (|y1-x1| + |y2-x2| + ... + |yn-xn|)
Example1:
input = 30.3, 2.4, 3.5
output = 30 2 4Example2:
input = 30.9, 2.4, 3.9
output = 31 2 4

先将所有floor(x)加起来统计出如果所有都floor的话还差多少,按照ceil以后需要加的价格排序,贪心取最小的补齐即可。代码如下:

# python
def roundNum(self, input):output = map(lambda x: floor(x), input)remain = int(round(sum(input)) - sum(output))it = sorted(enumerate(input), key=lambda x: x[1] - floor(x[1]))for _ in xrange(remain):output[it.pop()[0]] += 1return output//c++
vector<int> roundNumber(vector<double>& prices) {vector<int> ans;int got = 0;double all = 0.0;vector<pair<double, int> > s_prices;for (int i = 0; i < prices.size(); ++i) {double price = prices[i];int tmp = int(floor(price));got += tmp;ans.push_back(tmp);all += price;s_prices.push_back(make_pair(price, i));}sort (s_prices.begin(), s_prices.end(),[](pair<double, int> a, pair<double, int> b){ return a.first - floor(a.first) > b.first - floor(b.first);});for (int i = 0; i < int(round(all)) - got; ++i) {ans[s_prices[i].second]++;}return ans;
}

2D itertaor + remove()

leetcode 251(https://leetcode.com/problems/flatten-2d-vector)
实现二维数组的迭代器,加上remove操作。代码如下:

class Vector2D {
private:vector<vector<int> >::iterator row, iBegin, iEnd;vector<int>::iterator col;
public:Vector2D(vector<vector<int> > &nums) {row = nums.begin();iBegin = nums.begin();iEnd = nums.end();if (!nums.empty()) col = row->begin();}int next() {if (hasNext()) {int val = *col;col++;return val;}throw "It's empty already!";}bool hasNext() {while (row != iEnd && col == row->end()) {++row;if(row != iEnd)col = row->begin();}return row != iEnd;}void remove() {if (col == row->begin()) {auto pre = prev(row);while (pre != iBegin && (*pre).empty())pre = prev(pre);if (!(*pre).empty()) {(*pre).erase(prev((*pre).end()));} else {throw "Should call next() first!";}} else {(*row).erase(prev(col));col--;}}
};

ip2cidr

给出一个ipv4的range,找出最少的cidr可以覆盖这个range内的所有ip。

参考:
背景介绍https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
这个是个online转化工具http://www.ipaddressguide.com/cidr
大概的思路是group as much IPs as you can.
描述起来还真的麻烦呢,建议跑几个case,就理解了

code: http://stackoverflow.com/questions/33443914/how-to-convert-ip-address-range-to-cidr-in-java

解释: ——代表end-start能覆盖到的二进制位

start:xxxxxxx100000

end: xxxxxx——-这种情况下,先找出可以覆盖住xxxxxxx100000~xxxxxxx111111的cidr,start变为xxxxxxx100000 + 100000

end: xxxxxxxxx—-这种情况下,先找出可以覆盖住xxxxxxx100000~xxxxxxx101111的cidr,start变为xxxxxxx100000 + 10000

def ipToVal(ip):ip = ip.split(".")val = 0for x in ip:val = (val << 8) + int(x)return valdef ValToIp(val):ip, i = ["0"] * 4, 3while val:ip[i] = str(val % (1 << 8))val /= (1 << 8)i -= 1return ".".join(ip)def range2cidr(start, end):if not start or not end or start.count('.') != 3 or end.count('.') != 3:return Nonestart, end = ipToVal(start), ipToVal(end)if start > end:return Noneans = []while start <= end:firstOne = start & (-start)maxMask = 32 - int(log(firstOne, 2))maxDiff = 32 - int(floor(log(end - start + 1, 2)))maxMask = max(maxMask, maxDiff)ip = ValToIp(start)ans.append(ip + "/" + str(maxMask))start += 2 ** (32 - maxMask)return ans//C++
long ipToVal(string ip) {long val = 0;int i = 0;for (int j = 0; i < 4 && j < ip.length(); ++i) {auto nx = ip.find('.', j);if (nx == ip.npos) {val = (val << 8) + atoi(ip.substr(j).c_str());++i;break;}val = (val << 8) + atoi(ip.substr(j, nx - j).c_str());j = nx + 1;}if (i != 4) throw "The ip is incorrect";return val;
}string valToIp(long val) {string ip = "";for (int i = 0; i < 4; ++i) {ip = to_string(val % 256) + "." + ip;val /= 256;}ip.pop_back();return ip;
}vector<string> range2cidr(string start, string end) {// try...catchlong st = ipToVal(start), ed = ipToVal(end);vector<string> ans;while (st <= ed) {int lastOne = st & (-st);int maxMask = 32 - int((log(lastOne)/log(2)));int maxDiff = 32 - int(floor(log(ed - st + 1)/log(2)));maxMask = max(maxMask, maxDiff);string ip = valToIp(st);ans.push_back(ip + "/" + to_string(maxMask));st += int(pow(2, 32 - maxMask));}return ans;
}

Display Page list

用一个set来保存是否出现,加入以后删除原有元素,不够的话顺序补充

vector<vector<string> > paging(vector<string> items, int size) {vector<vector<string> > ans;const int n = items.size();for (int i = 0; i <= (n - 1) / size; ++i) {vector<string> tmp;unordered_set<string> st;for (auto it = items.begin(); it != items.end() && tmp.size() < size;) {if (st.count(*it)) {++it;continue;}st.insert(*it);tmp.push_back(*it);items.erase(it);}for (auto it = items.begin(); it != items.end() && tmp.size() < size;) {tmp.push_back(*it);items.erase(it);}ans.push_back(tmp);}return ans;
}

menu order

点菜,菜价格为double,问如何正好花完手里的钱
解法:把菜单价格*100转成整数,题目转换成leetcode 40.Combination Sum II(https://leetcode.com/problems/combination-sum-ii/?tab=Description)

void helper(vector<int> &dish, vector<vector<double> > &ans, vector<double> &cur, int idx, int money) {if (money == 0) {ans.push_back(cur);return;}if (idx == dish.size() || money < 0 || money < dish[idx])return;int cnt = 1;while (cnt * dish[idx] <= money) {cur.push_back(dish[idx] / 100.0);helper(dish, ans, cur, idx + 1, money - cnt * dish[idx]);++cnt;}while (--cnt) cur.pop_back();helper(dish, ans, cur, idx + 1, money);
}vector<vector<double> > menuOrder(vector<double>& dish, double money) {vector<int> tmp;vector<vector<double> > ans;vector<double> cur;for (auto d : dish)tmp.push_back(int(d * 100));sort(tmp.begin(), tmp.end());helper(tmp, ans, cur, 0, int(money * 100));return ans;
}

Hilbert Curve

Hilbert Curve(http://bit-player.org/extras/hilbert/hilbert-construction.html)
Hilbert曲线可以无限阶下去,从1阶开始,落在一个矩阵里,让你写个function,三个参数(x,y,阶数),return 这个点(x,y)是在这阶curve里从原点出发的第几步

int hilbertCurve(int x, int y, int iter) {if (iter == 0) return 1;int areaCnt = (1 << (iter * 2 - 2)); // 每一块区域边长的边界值int borderLen = (1 << (iter - 1)); // 区域移动的长度if (x >= borderLen && y >= borderLen) //右上角区域 = 前一阶往右上角移动borderLenreturn areaCnt * 2 + hilbertCurve(x - borderLen, y - borderLen, iter - 1);else if (x < borderLen && y >= borderLen) //左上角区域 = 前一阶往上移动borderLenreturn areaCnt + hilbertCurve(x, y - borderLen, iter - 1);else if (x < borderLen && y < borderLen) //右下角区域 = 前一阶按照y=x对称return hilbertCurve(y, x, iter - 1);else //右下角区域 = 前一阶按照y=-x对称,然后右移2*borderLen - 1,上移borderLen - 1// 设原来坐标(a,b) => (-b, -a) => (2*borderLen - 1 - b, borderLen - 1 - a) = (x, y)// => a = borderLen - 1 - y, b = 2*borderLen - 1 - xreturn areaCnt * 3 + hilbertCurve(borderLen - 1 - y, 2 * borderLen - 1 - x, iter - 1);
}

Alien Dictionary

leetcode 269

string alienOrder(vector<string> &words) {unordered_map<char, unordered_set<char> > mp;unordered_map<char, int> idx;unordered_set<char> st;queue<char> q;string ans = "";for (auto word : words) st.insert(word.begin(), word.end());for (int i = 0; i < words.size() - 1; ++i) {int j = 0, end = min(words[i].size(), words[i + 1].size());for (; j < end; ++j) {if (words[i][j] == words[i + 1][j]) continue;mp[words[i][j]].insert(words[i + 1][j]);break;}if (j == end && words[i].size() > words[i + 1].size())return ans;}for (auto m : mp) {for (auto s : m.second) {idx[s]++;}}for (auto s : st) {if (!idx.count(s)) {q.push(s);ans += s;}}while (!q.empty()) {char c = q.front();q.pop();auto next = mp[c];for (auto s : next) {if (--idx[s] == 0) {q.push(s);ans += s;}}}return ans.size() == st.size() ? ans : "";
}

有向图 求最少的点可以遍历所有点

(https://instant.1point3acres.com/thread/201190,https://instant.1point3acres.com/thread/197716)

解法,scc(strongly connected component)缩点 + 拓扑排序,太尼玛复杂了。。
解scc用了Kosaraju算法, 拓扑排序,代码如下:

void dfs(const vector<vector<bool> > &edges, vector<bool> &visited, vector<unordered_set<int> > &components, int idx, int id) {visited[idx] = true;if (components.size() == id) components.push_back({});components[id].insert(idx);for (int i = 0; i < edges.size(); ++i) {if (edges[i][idx] && !visited[i]) dfs(edges, visited, components, i, id);}
}void preDFS(const vector<vector<bool> > &edges, vector<bool> &visited, vector<int> &orders, int idx) {visited[idx] = true;orders.push_back(idx);for (int i = 0; i < edges.size(); ++i) {if (edges[idx][i] && !visited[i]) preDFS(edges, visited, orders, i);}
}vector<int> traverse(vector<vector<bool>> &edges) {const auto n = edges.size();vector<int> ans;if (n == 0) return ans;vector<bool> visited(n, false);vector<int> orders;// 记录伪拓扑排序的顺序vector<unordered_set<int> > components;//记录scc都包含哪些元素int id = 0;for (int i = 0; i < n; ++i) {if (!visited[i]) {preDFS(edges, visited, orders, i);}}fill(visited.begin(), visited.end(), false);for (int i = n - 1; i >= 0; --i) {if (!visited[orders[i]]) {dfs(edges, visited, components, orders[i], id);++id;}}unordered_map<int, int> in;unordered_map<int, unordered_set<int> > next;for (int from = 0; from < id; ++from) {for (int to = 0; to < id; ++to) {if (from == to) continue;bool found = false;for (auto x : components[from]) {if (found) break;for (auto y : components[to])if (edges[x][y]) {in[to]++;next[from].insert(to);found = true;break;}}}}for (int i = 0; i < id; ++i) {if (in[i] == 0) {ans.push_back(*components[i].begin());}}return ans;
}

c++(scc + union search)

typedef pair<int, int> pr;
typedef unordered_map<int, unordered_set<int> > connectInfo;
void fromDFS(int node, connectInfo from, vector<int>& order, unordered_set<int>& visited) {if(!visited.count(node)) {visited.insert(node);for(auto n : from[node])fromDFS(n, from, order, visited);order.insert(order.begin(), node);}
}void toDFS(int node, int root, connectInfo to, unordered_map<int, int>& components) {if(!components.count(node)) {components[node] = root;for(auto n : to[node])toDFS(n, root, to, components);}
}unordered_map<int, int> kosasrajus(connectInfo from, connectInfo to, const unordered_set<int>& nodes) {unordered_set<int> visited;unordered_map<int, int> components;vector<int> order;for(auto node : nodes)fromDFS(node, from, order, visited);for(auto node : order)toDFS(node, node, to, components);return components;
}vector<int> least_nodes(const vector<pr>& edges) {connectInfo from, to;unordered_set<int> nodes;vector<int> ans;for(auto edge : edges) {from[edge.first].insert(edge.second);to[edge.second].insert(edge.first);nodes.insert(edge.first);nodes.insert(edge.second);}unordered_map<int, int> components = kosasrajus(from, to, nodes);unordered_set<int> fromComponents, toComponents;for(auto edge : edges) {fromComponents.insert(components[edge.first]);if(components[edge.first] != components[edge.second]) {toComponents.insert(components[edge.second]);}}for(auto node : fromComponents)if(!toComponents.count(node))ans.push_back(node);return ans;
}

python:

def least_nodes(edges):pred = collections.defaultdict(set)succ = collections.defaultdict(set)for start, end in edges:pred[end].add(start)succ[start].add(end)components = kosarajus(pred, succ)component_pred = collections.defaultdict(set)component_succ = collections.defaultdict(set)for start, end in edges:if components[start] != components[end]:component_start = components[start]component_end = components[end]component_pred[component_end].add(component_start)component_succ[component_start].add(component_end)return set(component_succ.keys()) - set(component_pred.keys())def kosarajus(pred, succ):all_nodes = set(pred.keys()) | set(succ.keys())order = []visited = set()def visit(node):if node not in visited:visited.add(node)for out_neighbor in succ[node]:visit(out_neighbor)order.insert(0, node)for node in all_nodes:visit(node)components = {}def assign(node, root):if node not in components:components[node] = rootfor in_neighbor in pred[node]:assign(in_neighbor, root)for node in order:assign(node, node)return components

meeting room

给一组meetings(每个meeting由start和end时间组成)。求出在所有输入meeting时间段内没有会议,也就是空闲的时间段。每个subarray都已经sort好。N个员工,每个员工有若干个interval表示在这段时间是忙碌的。求所有员工都不忙的intervals。

循环merge,然后遍历空闲区间(ps:另一种解法很简单,参考:这题最简单的方法就是把所有区间都拆成两个点,然后排序,然后扫描,每次碰到一个点如果是左端点就把busy_employees加1,否则减1,等到每次busy_employees为0时就是一个新的区间。这样复杂度O(MlogM),M是总共区间数。)

//merge and search
vector<pr> merge(vector<pr> ft, vector<pr> sd) {//c++, mergeif(ft.empty()) return sd;if(sd.empty()) return ft;vector<pr> ans;const int m = ft.size(), n = sd.size();int i = 0, j = 0;pr tmp(1, 1);while(i < m || j < n) {if ((i == m || tmp.second < ft[i].first) && (j == n || tmp.second < sd[j].first)) {ans.push_back(tmp);if(i == m) tmp = sd[j];else if(j == n) tmp = ft[i];else {tmp.first = min(ft[i].first, sd[j].first);tmp.second = min(ft[i].second, sd[j].second);}}if(i < m && ft[i].first <= tmp.second)tmp.second = max(tmp.second, ft[i++].second);if(j < n && sd[j].first <= tmp.second)tmp.second = max(tmp.second, sd[j++].second);}ans.push_back(tmp);return ans;
}
vector<pr> meetingRoom(vector<vector<pr> > meetings) {vector<pr> ans, tmp;const int n = meetings.size();if(n == 0) return ans;tmp = meetings[0];for(int i = 1; i < n; ++i) {tmp = merge(tmp, meetings[i]);}if(tmp[0].first > 1)ans.push_back(make_pair(1, tmp[0].first));for(int i = 0; i < tmp.size() - 1; ++i)ans.push_back(make_pair(tmp[i].second, tmp[i + 1].first));return ans;
}//break and sort: C++
typedef pair<int, int> pr;
typedef pair<int, bool> timePoint;
vector<pr> meetingRoom(vector<vector<pr> > meetings) {vector<timePoint> times;vector<pr> ans;if ( meetings.empty()) return ans;for (auto meeting : meetings) {for (auto interval : meeting) {times.push_back(make_pair(interval.first, true));times.push_back(make_pair(interval.second, false));}}sort(times.begin(), times.end());int startCnt = 0, preTime = times[0].first;for(auto time : times) {bool starting = time.second;if (starting) {if (startCnt == 0 && time.first > preTime) {ans.push_back(make_pair(preTime, time.first));}++startCnt;} else {if (startCnt == 1) preTime = max(preTime, time.first);--startCnt;}}return ans;
}//break and sort: python
def find_free_time(schedules):
moment_status = []for person_schedule in schedules:for interval in person_schedule:moment_status.append((interval[0], True))moment_status.append((interval[1], False))
moment_status.sort()
free_start = moment_status[0][0]
busy_count = 0
available_intervals = []
for moment, become_busy in moment_status:if become_busy:if busy_count == 0:if moment > free_start:available_intervals.append((free_start, moment))busy_count += 1else:if busy_count == 1:free_start = momentbusy_count -= 1
return available_intervals

preference list

每个人都有一个preference的排序,在不违反每个人的preference的情况下得到总体的preference的排序 拓扑排序解决(https://instant.1point3acres.com/thread/207601)

vector<int> preferenceList(vector<vector<int> > &preList) {unordered_map<int, unordered_set<int> > mp;unordered_map<int, int> in;vector<int> ans;for(auto lt : preList) {for(int i = 1; i < lt.size(); ++i)mp[lt[i - 1]].insert(lt[i]);}for(auto m : mp)for(auto s : m.second)in[s]++;queue<int> q;for(int i = 0; i < preList.size(); ++i)if(!in.count(i)) {q.push(i);ans.push_back(i);}while(!q.empty()) {int c = q.front();q.pop();auto next = mp[c];for(auto s : next) {if(--in[s] == 0) {q.push(s);ans.push_back(s);}}}return ans;
}

buddy list

你和你的兄弟都有一个wishlist,找出和你相似度最高的。follow up是给出一个max值,找出你的buddy的wishlist里不在你的wishlist里的最多max个城市,根据buddy和你的重合程度来排序

例如:
你的wishlist是 a,b,c,d

buddy1 的wishlist 是 a,b,e,f, 有两个和你的一样,所以是你的buddy

buddy2 的wishlist 是 a,c,d,g, 有三个和你的一样,也是你的budy

问题是输出一个size最多为max的推荐城市列表。当size为10时,buddy1和buddy2的wishlist中不在你的wishlist中的城市都可以加入推荐中,因为buddy2的重合度更高,所以先输出buddy2中的,所以推荐为 g,e,f 当size为2时,推荐是g,e 或 g,f

代码我只写了重合度排名,推荐的话可以按照相似度从高到低遍历,找出不在你的wishlist中的输出,输出过程中可以标记是否已经输出

def find(self, nums, nums2):return sorted([(sum([num in set(nums) for num in nums2[i]]) / float(len(nums2[i])), i)for i in xrange(len(nums2))])

flight ticket list

每一项包括departure, arrival, cost,然后给一个整数k, 表示最多允许k次中转。给定起始地点A,到达地点B, 要求输出从A到B的最小花费,最多k次中转。BFS一层一层扫。

def min_cost(flights, start, end, k):info = collections.defaultdict(set)for tour, cost in flights:st, ed = tour.split("->")info[st].add((ed, cost))cur_level = {start: 0}ans = 0x7FFFFFFfor _ in xrange(k + 1):next_level = {}for port, cur_cost in cur_level.iteritems():for nx, cost in info[port]:if nx == end:ans = min(ans, cost + cur_cost)else:if nx not in next_level:next_level[nx] = cost + cur_costelse:next_level[nx] = min(next_level[nx], cost + cur_cost)cur_level = next_levelreturn ans///C++: 太丑
typedef pair<string, int> costInfo;
int minCostFlight(const vector<string>& flights, string start, string end, int k) {unordered_map<string, set<costInfo> > costMap;unordered_map<string, int> reached[2];int ans = INT_MAX;for (auto flight : flights) auto nx = flight.find("->", 0);auto comma = flight.find(',', nx + 2);string st = flight.substr(0, nx);string ed = flight.substr(nx + 2, comma - nx - 2);int cost = atoi(flight.substr(comma + 1).c_str());costMap[st].insert(make_pair(ed, cost));}reached[0][start] = 0;for (int i = 0, j = 0; i <= k; ++i) {int nxIdx = (j + 1) % 2;reached[nxIdx].clear();for (auto st : reached[j]) {for(auto ed : costMap[st.first]) {if (ed.first == end) {ans = min(ans, ed.second + st.second);} else {if (!reached[nxIdx].count(ed.first))reached[nxIdx][ed.first] = ed.second + st.second;elsereached[nxIdx][ed.first] = min(reached[nxIdx][ed.first], ed.second + st.second);}}}j = nxIdx;}return ans;
}

URL Shortener

(https://instant.1point3acres.com/thread/196339)

看描述好像是url里的id如果有某些位置大小写换了会导致原来的url decode有问题,需要重写encode方法,回溯改某些位的大小写判断

class decodeURL {
public:int decode(string url) {string dUrl = "kljJJ324hijkS_";if (url == dUrl) return 848662;return -1;}int decodeFind(string url) {return helper(url, 0);}private:int helper(string s, int idx) {if (idx == s.length())return decode(s);if (isalpha(s[idx])) {int uid = helper(s.substr(0, idx) + char(tolower(s[idx])) + s.substr(idx + 1), idx + 1);int lid = helper(s.substr(0, idx) + char(toupper(s[idx])) + s.substr(idx + 1), idx + 1);if (uid != -1 || lid != -1)return uid != -1 ? uid : lid;return -1;} else {return helper(s, idx + 1);}}
};

wizards

There are 10 wizards, 0-9, you are given a list that each entry is a list of wizards known by wizard. Define the cost between wizards and wizard as square of different of i and j. To find the min cost between 0 and 9.

说白了,就是带权重的最短距离,最优解是Dijkstra algorithm。似乎面试官说,只要普通的BFS能得到解也是可以的,Dijkstra我最近正好写过,所以也写出来了。(https://instant.1point3acres.com/thread/218032)

def min_distance(wizards, start=0, end=9):# info = collections.defaultdict(set)# for idx, wizard in enumerate(wizards):#     info[idx] = set(wizard)cur_level = {start: 0}ans = 0x7FFFFFFFfor _ in xrange(10):next_level = {}for idx, cur_cost in cur_level.iteritems():if idx >= len(wizards):continuefor nx in wizards[idx]:cost = cur_cost + (nx - idx) ** 2if nx == end:ans = min(ans, cost)else:if nx not in next_level:next_level[nx] = costelse:next_level[nx] = min(next_level[nx], cost)cur_level = next_levelreturn ansunordered_map<int, int> bfs(const unordered_map<int, int>& preLevel, unordered_map<int, unordered_set<int> >& next, int& ans, int k, int end) {unordered_map<int, int> nextLevel;for ( auto pre : preLevel) {for (auto nx : next[pre.first]) {int dis = (nx - pre.first) * (nx - pre.first) + pre.second;if (nx == end) {ans = min(ans, dis);} else if(!nextLevel.count(nx)) {nextLevel[nx] = dis;} elsenextLevel[nx] = min(nextLevel[nx], dis);}}return k == 1 ? nextLevel : bfs(nextLevel, next, ans, k - 1, end);
}int wizards(const vector<vector<int> > &wizards, int start, int end) {unordered_map<int, unordered_set<int> > next;unordered_map<int, int> curLevel;int ans = INT_MAX;curLevel[start] = 0;for (int i = 0; i < wizards.size(); ++i) {for (auto nx : wizards[i]) {next[i].insert(nx);}}bfs(curLevel, next, ans, end, end);return ans;
}

模拟倒水

water land。 比如terrian是[3,2,1,2] print出来就是

*

* *   *

* * * *

* * * *

然后给你一个dumpPoint,一个waterAmount,比如dumpPoint 1, waterAmount 2,因为有重力,所以是从index 2开始加水

*

* * w *

* * * *

* * * *

terrian两边是最高,模拟,先向左找到非递增的最低点,如果该点和dumpPoint一样高,往右继续找非递增的最低点,如果一样高就放到dumpPoint,不一样的话放置在非递增的最低点

void getWaterLevel(vector<int> &height, int position, int count) {if(height.empty()) return;const int n = height.size();vector<int> water(n, 0);while(count--) {int putLocation = position;int left = position, right = position;while(left >= 1) {if(height[left - 1] + water[left - 1] > height[left] + water[left]) break;--left;}if(height[left] + water[left] < height[position] + water[position])putLocation = left;else {while(right < n - 1) {if(height[right + 1] + water[right + 1] > height[right] + water[right]) break;++right;}if(height[right] + water[right] < height[position] + water[position])putLocation = right;}water[putLocation]++;}int highest = 0;for(int i = 0; i < n; ++i)if(height[i] + water[i] > highest)highest = height[i] + water[i];for(int h = highest; h >= 1; --h) {for(int i = 0; i < n; ++i) {if(height[i] + water[i] < h) cout<<" ";else if(height[i] < h) cout<<"w";else cout<<"*";}cout<<endl;}
}

text justification

leetcode 68(https://leetcode.com/problems/text-justification/?tab=Description)

vector<string> justify(vector<string> &words, int L) {vector<string> ans;const int n = words.size();for (int i = 0; i < n;) {int num = 0, len = 0;while (i + num < n && words[i + num].size() + len <= L - num) {len += words[i + num].size();++num;}string tmp = words[i];for (int j = 1; j < num; ++j) {if (i + num >= n) tmp += " ";else tmp += string((L - len) / (num - 1) + (j  <= (L - len) % (num - 1)), ' ');tmp += words[i + j];}tmp += string(L - tmp.size(), ' ');ans.push_back(tmp);i += num;}return ans;
}

string pyramids transition matrix

给一个满二叉树的所有叶子,比如 A B C D E F, 然后给一个map,记录了左右孩子分别给了的时候,父亲节点可能的值。例如 左 A 右 B =》 AC,意味着倒数第二层第一个节点可以是A或者是C。然后要求是给几个字母,问这个树的root节点是否可能是这几个字母之一。follow up是加速,记忆化搜索(不是很好写)。

def generate_status(all_status, matrix):if len(all_status) == 1:return all_status[0]next_all_status = []for i in xrange(len(all_status) - 1):cur_status = set()for first in all_status[i]:for second in all_status[i + 1]:cur_status |= set(list(matrix[first][second]))next_all_status.append(cur_status)return generate_status(next_all_status, matrix)def is_legal_status(nodes, status, matrix):all_status = [set(node) for node in nodes]return status in generate_status(all_status, matrix)nodes = "ABCD"
matrix = collections.defaultdict(lambda: collections.defaultdict(list))
matrix['A']['A'] = ['B']
matrix['A']['B'] = ['A', 'C']
matrix['A']['C'] = ['D']
matrix['A']['D'] = ['A']
matrix['B']['A'] = ['D']
matrix['B']['B'] = ['B', 'C']
matrix['B']['C'] = ['A']
matrix['C']['D'] = ['B']
print is_legal_status(nodes, 'D', matrix)typedef unordered_map<char, unordered_map<char, unordered_set<char> > > matrixInfo;
void generateStatus(vector<unordered_set<char> >& allStatus, matrixInfo& matrix) {if (allStatus.size() == 1) return;const int n = allStatus.size();for (int i = 0; i < n - 1; ++i) {unordered_set<char> st;for (auto first : allStatus[i]) {for (auto second : allStatus[i + 1]) {st.insert(matrix[first][second].begin(), matrix[first][second].end());}}allStatus[i] = st;}allStatus.pop_back();generateStatus(allStatus, matrix);
}bool checkStatus(matrixInfo& matrix, char result, const string status) {vector<unordered_set<char> > allStatus;for (auto c : status) {unordered_set<char> tmp;tmp.insert(c);allStatus.push_back(tmp);}generateStatus(allStatus, matrix);return allStatus[0].count(result) != 0;
}int main() {matrixInfo mi;mi['A']['A'].insert('B');mi['A']['B'].insert('A');mi['A']['B'].insert('C');mi['A']['C'].insert('D');mi['A']['D'].insert('A');mi['B']['A'].insert('D');mi['B']['B'].insert('B');mi['B']['B'].insert('C');mi['B']['C'].insert('A');mi['C']['D'].insert('B');cout<<checkStatus(mi, 'A', "ABCD")<<endl;
}

sliding game

九宫格,一共8个方块,从1-8,一个方块空出来,然后打乱之后通过SLIDE还原,这个题要推广到N宫格,先实现这个游戏,然后对于一个任意的BOARD,要你把他解出来

def dis(x, y):  # A* evaluation funcreturn (x - 2) ** 2 + (y - 2) ** 2def play(board):m, n = len(board), len(board[0])x, y = 0, 0for i in xrange(m):for j in xrange(n):if board[i][j] == '0':x, y = i, jboard_key = ''.join(''.join(row) for row in board)heap = [(dis(x, y), x, y, board_key)]visited = set()while heap:_, x, y, cur = heapq.heappop(heap)if cur in visited:continuevisited.add(cur)if cur == "123456780":return Truefor dx, dy in zip((1, -1, 0, 0), (0, 0, 1, -1)):new_x, new_y = x + dx, y + dyif 0 <= new_x < m and 0 <= new_y < n:pos1, pos2 = x * m + y, new_x * m + new_ynew_board = list(cur)new_board[pos1], new_board[pos2] = new_board[pos2], new_board[pos1]heapq.heappush(heap, (dis(new_x, new_y), new_x, new_y, ''.join(new_board)))return Falsetypedef tuple<int, int, int, string> boardInfo;
bool validSlidingGame(vector<vector<int> >& board) {const int m = board.size(), n = board[0].size();auto dis = [](int x, int y, int z, int p) {return (x - z) * (x - z) + (y - p) * (y - p); };int x = 0, y = 0;string key = "";const int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};priority_queue<boardInfo> pq;unordered_set<string> visited;for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (board[i][j] == 0) {x = i, y = j;}key += to_string(board[i][j]);}}pq.push(make_tuple(-dis(x, y, m - 1, n - 1), x, y, key));visited.insert(key);while (!pq.empty()) {auto tp = pq.top();pq.pop();string curKey;tie(ignore, x, y, curKey) = tp;
//        x = get<1>(tp), y = get<2>(tp);
//        auto curKey = get<3>(tp);if (curKey == "123456780") return true;for (int i = 0; i < 4; ++i) {int newX = x + dir[i][0];int newY = y + dir[i][1];if (newX >= 0 && newX < m && newY >= 0 && newY < n) {swap(curKey[x * m + y], curKey[newX * m + newY]);if (!visited.count(curKey)) {pq.push(make_tuple(-dis(newX, newY, m - 1, n - 1), newX, newY, curKey));visited.insert(curKey);}}}}return false;
}

find median from large file of integers

https://instant.1point3acres.com/thread/159344
二分查找
思路就是:先找在INT_MIN和INT_MAX的median(0?),然后读large file of integers,找出比这个数小的个数是否有一半,然后调整二分的边界

double findNth(int N, int left, int right) {while(left <= right){int guess = (left + right) / 2;int x, cnt = 0, next = right;while(x = readFile()) {if(x < guess) ++cnt;else next = min(next, x);}if(cnt == N - 1)return next;if(cnt < N - 1)left = guess;elseright = guess - 1;}return 0.0;
}double findMedian() {int len = 0;while(readFile()) ++len;if(len & 0x1) return findNth(len >> 1, INT_MIN, INT_MAX);int x = findNth(len >> 1, INT_MIN, INT_MAX);int y = findNth(1 + (len >> 1), x, INT_MAX);return double(x + y) / 2;
}

Multiply Strings

但是string里面的数可以为负

leetcode 43题,多了个负数的情况(https://leetcode.com/problems/multiply-strings/?tab=Description)

#include <iterator>
#include <algorithm>
#include <vector>typedef vector<int> bigInt;
bigInt make_bigInt(string num) {bigInt tmp;transform(num.rbegin(), num.rend(), back_inserter(tmp), [](char c) { return c - '0';});return tmp;
}
string make_string(bigInt num) {string tmp;transform(find_if(num.rbegin(), prev(num.rend()), [](int c){ return c != 0;}), num.rend(),back_inserter(tmp), [](int c) { return c + '0';});return tmp;
}
bigInt multiply(bigInt const& n1, bigInt const& n2) {bigInt n(n1.size() + n2.size());for (int i = 0; i < n1.size(); ++i)for (int j = 0; j < n2.size(); ++j) {n[i + j] += n1[i] * n2[j];n[i + j + 1] += n[i + j] / 10;n[i + j] %= 10;}return n;
}string multiply(string num1, string num2) {if(num1.empty() || num2.empty()) return "0";bool sign = true;if (num1[0] == '-' || num1[0] == '+') {if (num1[0] == '-') sign = !sign;num1.sustr(1);}if (num2[0] == '-' || num2[0] == '+') {if (num2[0] == '-') sign = !sign;num2.sustr(1);}string ans = make_string(multiply(make_bigInt(num1), make_bigInt(num2)));if (ans == "0") return ans;return (sign ? "" : "-") + ans;
}

CSV PARSER

举个例子:
给定一个CSV文件,格式是 “some_name|some_address|some_phone|some_job”
要求输出Json format “{name:some_name, address:some_addres,phone:some_phone, job:some_job}”
输入内容中有些特殊符号要注意处理

vector<string> parseCSV(string s) {vector<string> ans;bool inQuote = false;string tmp = "";for(int i = 0; i < s.length(); ++i) {if(inQuote) {if(s[i] == '"') {if(i == s.length() - 1) {ans.push_back(tmp);return ans;} else if(s[i + 1] == '"') {tmp += '"';++i;} else {ans.push_back(tmp);tmp = "";inQuote = false;i++;}} else tmp += s[i];} else {if(s[i] == '"')inQuote = true;else if(s[i] == ',') {ans.push_back(tmp);tmp = "";} else tmp += s[i];}}if(!tmp.empty()) ans.push_back(tmp);return ans;
}int main() {string ss[] = {"John,Smith,john.smith@gmail.com,Los Angeles,1", "\"Alexandra \"\"Alex\"\"\",Menendez,alex.menendez@gmail.com,Miami,1"};for(auto s : ss) {auto parsed = parseCSV(s);for (int i = 0; i < parsed.size() - 1; ++i)cout << parsed[i] << "|";cout<<parsed[parsed.size() - 1]<<endl;}return 0;
}

boggle game

(https://instant.1point3acres.com/thread/201695)

这题面试来搞也太变态了,先用trie找出所有单词出现的路径map,然后dfs找出map里不重复的最大的。代码未验证~

struct Node {bool isWord = false;string word;Node *next[26];Node() {}
};struct Trie {Node *root;Trie() {root = new Node();}void buildTrie(const vector<string>& &words) {for(auto word : words) {Node *cur = root;for(auto c : word) {int idx = c - 'a';if(!cur->next[idx])cur->next[idx] = new Node();cur = cur->next[idx];}cur->isWord = true;cur->word = word;}}
};const int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
void searchBoard(const vector<vector<char> >& board, vector<vector<bool> >& visited, int x, int y, Node* root,vector<pr>& path, unordered_map<string, vector<vector<pr>> >& mp) {if(x < 0 || x > board.size() || y < 0 || y > board[0].size() || visited[x][y])return;int idx = board[x][y] - 'a';if(!root->next[idx]) return;root = root->next[idx];path.push_back(make_pair(x, y));visited[x][y] = true;if(root->isWord) mp[root->word].push_back(path);for(int i = 0;i < 4; ++i)searchBoard(board, visited, x + dir[i][0], y + dir[i][1], root, path, mp);visited[x][y] = false;path.pop_back();
}
void dfs(int& ans, int cur, const vector<string>& words, vector<vector<bool> >& visited, unordered_map<string, vector<vector<pr>> >& mp, int idx) {if(idx == words.size()) {ans = max(ans, cur);return;}if(ans >= cur + words.size() - idx) return;string word = words[idx];if(mp.count(word)) {for (auto pts : mp[word]) {int cnt = 0;for (auto pt : pts) {if (visited[pt.first][pt.second]) break;cnt++;}if (cnt == word.size()) {for (auto pt : pts) visited[pt.first][pt.second] = true;dfs(ans, cur + 1, words, visited, mp, idx + 1);for (auto pt : pts) visited[pt.first][pt.second] = false;}}}dfs(ans, cur, words, visited, mp, idx + 1);
}int findWords(const vector<vector<char> >& board, const vector<string>& words) {if(board.empty() || words.empty()) return 0;Trie trie;trie.buildTrie(words);const auto m = board.size(), n = board[0].size();unordered_map<string, vector<vector<pr>> > mp;for(int i = 0; i < m; ++i)for(int j = 0; j < n; ++j) {vector<vector<bool> > visited(m, vector<bool>(n, false));vector<pr> path;searchBoard(board, visited, i, j, trie.root, path, mp);}vector<vector<bool> > visited(m, vector<bool>(n, false));int ans = 0;dfs(ans, 0, words, visited, mp, 0);return ans;
}

转载于:https://www.cnblogs.com/vector11248/p/11473793.html

Airbnb 面试题汇总相关推荐

  1. Java面试题汇总及答案2021最新(序列化含答案)

    Java面试题汇总及答案2021最新(序列化含答案) 为大家整理了2021最新的Java面试题及答案下载,这套Java面试题总汇已经汇总了Java基础面试到高级Java面试题,几乎涵盖了作为一个Jav ...

  2. Java面试题汇总及答案2021最新(ioNio)

    Java面试题汇总及答案2021最新(io&Nio) 最近给大家整理了一批Java关于io和nio的面试题一共15题,是20201最新时间整理的,并且都含答案打包下载. 适宜阅读人群 需要面试 ...

  3. access汇总含义_2020最新大厂内部 PHP 高级工程师面试题汇总(二)

    51.数据库中的存放了用户 ID, 扣费很多行,redis 中存放的是用户的钱包,现在要写一个脚本,将数据库中的扣费记录同步到 redis 中,每 5 分钟执行一次.请问要考虑哪些问题? 思路:生产者 ...

  4. 程序员必看 c++笔试题汇总

    ①链表反转 单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题.比如一个链表是这样的: 1->2->3->4->5 通过反转后成为5->4->3-& ...

  5. 超全!iOS 面试题汇总

    超全!iOS 面试题汇总 2015-10-20 CocoaChina 作者:Job_Yang 之前看了很多面试题,感觉要不是不够就是过于冗余,于是我将网上的一些面试题进行了删减和重排,现在分享给大家. ...

  6. 专业软件测试面试题汇总

    专业软件测试面试题汇总 一.如何保证测试用例能达到全部覆盖? 1.需要测试人员有丰富的测试经验 2.需求分析透彻,已确定好测试范围 3.通过测试用例评审 二.版本测试通过的标准是什么? 1.用例测试通 ...

  7. web前端兼容性面试题汇总!

    web前端兼容性面试题汇总 一.html部分 1.H5新标签在IE9以下的浏览器识别 html5shiv.js下载地址 2.ul标签内外边距问题ul标签在IE6\IE7中,有个默认的外边距,但是在IE ...

  8. java 正则表达式 替换字符串img标签的路径_python面试题汇总第06期-正则表达式(内附7题及答案)...

    1.python正则表达式中匹配(match)和查找(search)的区别 答:正则表达式中match和search的方法比较相似 相同点:都是在一个字符串s中寻找pat子字符串,如果能找到,就返回一 ...

  9. dotNET面试题汇总系列连载(1):基础语法

    点击上方"dotNET全栈开发","设为星标" 加"星标★",每天11.50,好文必达 全文约4000字,预计阅读时间8分钟 马上要到202 ...

  10. C语言试题汇总200例目录

    1.温馨提示 C语言试题汇总里可用于计算机二级C语言笔试.机试.研究生复试中C程序设计科目.帮助C语言学者打好程序基础.C语言基础,锻炼您的逻辑思维和解决问题的能力,帮助你成为C语言笔试.机试解题高手 ...

最新文章

  1. 北京对无人车的热情,华尔街都感受到了
  2. 设计微服务架构需要掌握的基础知识
  3. cordova打包安卓app
  4. android 移除fragment,Android Viewpager+Fragment取消预加载及Fragment方法的学习
  5. 《Linux Device Drivers》第十六章 块设备驱动程序——note
  6. Servlet+Jsp实现图片或文件的上传功能
  7. vue-cli2.0webpack的理解
  8. 哥廷根大学计算机博士,德国哥廷根大学 单分子光学 招博士 (75% TV-L E13 工资)...
  9. Snipaste操作指南
  10. 华北电力计算机技术考研难度,华北电力大学(专业学位)计算机技术考研难吗
  11. 距离度量准则(转载)
  12. php获取电脑硬件配置,如何查看电脑硬件配置
  13. Linux下怎么进入波浪线目录,linux 波浪线 ~ 使用方法
  14. Jude——用例图和活动图
  15. MATLAB数学建模(二):评估股票的价值和风险
  16. 清华计算机专业考研经验谈
  17. 「力扣数据库」183. 从不订购的客户(第五天)
  18. 有沃更精彩,沃课堂理想的移动学习平台
  19. python学习Day-8
  20. 为什么蝙蝠一直显示无法连接服务器,Doodle Jump无法连接服务器是什么原因

热门文章

  1. Security+ 学习笔记36 嵌入式系统安全
  2. nyoj--860--又见01背包--01背包的变形
  3. HDOJ--1203--I NEED A OFFER!
  4. linux/unix 上那些炫酷的命令行工具(一)
  5. win10家庭版远程连接 要求的函数不受支持
  6. 【DATAGUARD】物理dg在主库丢失归档文件的情况下的恢复(七)
  7. Java中集合list的add方法添加的不是值COPY而是地址
  8. MongoDB日志工作流程
  9. MyEclipse+Tomcat+JSP开发环境配置
  10. A simple Android example,including Intent/View/...