dfs
class Solution {
public:
bool exist(vector<vector<char> > &board, string word) {
if(board.size()==0) return false;
if(word.length()==0) return true;
int row=board.size(),col=board[0].size();
vector<vector<bool>>used(row,vector<bool>(col,false));
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
if(search(board,word,0,i,j,used))
return true;
return false;
}
bool search(vector<vector<char> > &board, string word, int index,int i,int j, vector<vector<bool>>&used){
if(index==word.length()) return true;
if(i<0||j<0||i>=board.size()||j>=board[0].size()||used[i][j]||word[index]!=board[i][j])
return false;
used[i][j]=true;
bool res=search(board,word,index+1,i-1,j,used)
||search(board,word,index+1,i+1,j,used)
||search(board,word,index+1,i,j-1,used)
||search(board,word,index+1,i,j+1,used);
used[i][j]=false;
return res;
//the above two line can be replaced by:
//if(res) return true;
//used[i][j]=false;
//return false;
}
};
//another flavor
public boolean exist(char[][] board, String word) {
if(board == null) return false;
if(word == null || word.length() == 0) return true;
boolean [][] visited = new boolean[board.length][board[0].length];
for(int i = 0; i < board.length; i++)
for(int j = 0; j < board[0].length; j++)
if(DFS(board, i, j, word, 0, visited)) return true;
return false;
}
public boolean DFS(char[][] b, int i, int j, String word, int index, boolean[][] v){
if(v[i][j] || b[i][j] != word.charAt(index)) return false;
if(index == word.length() - 1) return true;
v[i][j] = true;
if(i != 0 && DFS(b, i - 1, j, word, index + 1, v)) return true;
if(i != b.length - 1 && DFS(b, i + 1, j, word, index + 1, v)) return true;
if(j != 0 && DFS(b, i, j - 1, word, index + 1, v)) return true;
if(j != b[0].length - 1 && DFS(b, i, j + 1, word, index + 1, v)) return true;
v[i][j] = false;
return false;
}
Friday, November 21, 2014
Thursday, November 20, 2014
facebook面经 interval problem
determine the minimum number of meeting rooms needed to hold all the
meetings.
Input array(pair(1, 4), pair(2,3), pair(3,4), pair(4,5))
Output: 2
Ans:
treat each start and end time as a point, sort the points,
now process each point in order,
if hit a start time, cnt ++
if hit an end time, cnt --
the max of cnt in the process is the number of meeting rooms needed.
there is one catch
这个解法有个注意事项,如果interval 1的start time 和interval 2 的end time相等
,应该把 interval 2的 end time排在前面
不然像(2, 3),(3, 4)这样的可能返回2,实际应该返回1.
The following is a wrong dp solution:
按pair.first sort,
f[i]为从第0个到第i个时间段需要的最小房间数
那么if(pair[i].first>=pair[i-1].second) f[i]=f[i-1]
else f[i]=f[i-1]+1
counterexample:(1,3)(2,6),(4,5)
the result of the algo is 3, but the correct answer is 2
meetings.
Input array(pair(1, 4), pair(2,3), pair(3,4), pair(4,5))
Output: 2
Ans:
treat each start and end time as a point, sort the points,
now process each point in order,
if hit a start time, cnt ++
if hit an end time, cnt --
the max of cnt in the process is the number of meeting rooms needed.
there is one catch
这个解法有个注意事项,如果interval 1的start time 和interval 2 的end time相等
,应该把 interval 2的 end time排在前面
不然像(2, 3),(3, 4)这样的可能返回2,实际应该返回1.
The following is a wrong dp solution:
按pair.first sort,
f[i]为从第0个到第i个时间段需要的最小房间数
那么if(pair[i].first>=pair[i-1].second) f[i]=f[i-1]
else f[i]=f[i-1]+1
counterexample:(1,3)(2,6),(4,5)
the result of the algo is 3, but the correct answer is 2
Google 电面两道算法题
2014.11. from 1point3
1.找出missing number 范围
number范围[0,99]
2. 找出一个数由最少几个平方的和的组成
例子:
input: 14 output: 9 ,4 , 1 虽然也能由1 +1 +....+1组成 但长度是14 不是最优解
1.找出missing number 范围
number范围[0,99]
input: [0, 1, 2,50 , 52, 75]
output: "3-49,51,53-74,76-99"
2. 找出一个数由最少几个平方的和的组成
例子:
input: 14 output: 9 ,4 , 1 虽然也能由1 +1 +....+1组成 但长度是14 不是最优解
input: 50 ouput : 25, 25
Ans:
1. idea from the solution the leetcode problem: Longest Consecutive Sequence
use the map property that the key is sorted
1. idea from the solution the leetcode problem: Longest Consecutive Sequence
use the map property that the key is sorted
int merge(map<int, int> &amap, int left, int right) {
int upper = right + amap[right] - 1;
int lower = left - amap[left] + 1;
int len = upper - lower + 1;
amap[upper]= len;
amap[lower]= len;
return len;
}
//the range is [start, end]
int missingRanges(vector<int> & a,int start,int end) {
map<int, int> amap;
for (int i=0;i<a.size();i++) {
if (amap.count(a[i])) continue;
amap[a[i]]=1;
if (amap.count(a[i]-1)) {
merge(amap, a[i]-1, a[i]);
}
if (amap.count(a[i]+ 1) ){
merge(amap, a[i], a[i]+1);
}
}
for(auto it=amap.begin();it!=amap.end();it++){
if(start==it->first){
start=it->first+it->second;
}
else if(start<it->first){
cout<<start<<"-"<<it->first-1<<", ";
start=it->first+it->second;
}
}
if(start<=end)
cout<<start<<"-"<<end<<"\n";
return 0;
}
2. dp, first one
int minNumber1(int num){
vector<int> dp(num+1);
dp[0]=0;
for(int i=1;i<=(int)(sqrt((double)num));i++)
dp[i*i]=1;
for(int i=2;i<=num;i++){
if(dp[i]!=0) continue;
int amin=INT_MAX;
for(int k=1;k<=i/2;k++){
amin=min(amin,dp[k]+dp[i-k]);
if(amin==2)
break;
}
dp[i]=amin;
}
return dp[num];
}
//another flavor, faster.
int minNumber2(int n){
vector<int> f(n+1);
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= n ; i++){
int amin = INT_MAX;
for(int k=1;k*k<=i;k++){
int cur = 1 + f[i-k*k];
amin = min(amin, cur);
}
f[i] = amin;
}
return f[n];
}
int upper = right + amap[right] - 1;
int lower = left - amap[left] + 1;
int len = upper - lower + 1;
amap[upper]= len;
amap[lower]= len;
return len;
}
//the range is [start, end]
int missingRanges(vector<int> & a,int start,int end) {
map<int, int> amap;
for (int i=0;i<a.size();i++) {
if (amap.count(a[i])) continue;
amap[a[i]]=1;
if (amap.count(a[i]-1)) {
merge(amap, a[i]-1, a[i]);
}
if (amap.count(a[i]+ 1) ){
merge(amap, a[i], a[i]+1);
}
}
for(auto it=amap.begin();it!=amap.end();it++){
if(start==it->first){
start=it->first+it->second;
}
else if(start<it->first){
cout<<start<<"-"<<it->first-1<<", ";
start=it->first+it->second;
}
}
if(start<=end)
cout<<start<<"-"<<end<<"\n";
return 0;
}
2. dp, first one
int minNumber1(int num){
vector<int> dp(num+1);
dp[0]=0;
for(int i=1;i<=(int)(sqrt((double)num));i++)
dp[i*i]=1;
for(int i=2;i<=num;i++){
if(dp[i]!=0) continue;
int amin=INT_MAX;
for(int k=1;k<=i/2;k++){
amin=min(amin,dp[k]+dp[i-k]);
if(amin==2)
break;
}
dp[i]=amin;
}
return dp[num];
}
//another flavor, faster.
int minNumber2(int n){
vector<int> f(n+1);
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= n ; i++){
int amin = INT_MAX;
for(int k=1;k*k<=i;k++){
int cur = 1 + f[i-k*k];
amin = min(amin, cur);
}
f[i] = amin;
}
return f[n];
}
Quick sort
quicksort(A,p,r){
if (p<r){
q=partition(A,p,r);
quicksort(A,p,q-1);
quicksort(A,q+1,r);
}
}
partition(A,p,r){
i=p-1;
for(int j=p;j<r;j++){
if (A[j]<=A[r]){
swap(A[++i],A[j])
}
}
swap(A[i+1],A[r]);
return i+1;
}
Wednesday, November 19, 2014
string question: example using kmp
A家的电面题:
有一种String,是把一个更短的String重复n次而构成的,那个更短的String长度至少为
2,输入一个String写代码返回T或者F
例子:
"abcabcabc" Ture 因为它把abc重复3次构成
"bcdbcdbcde" False 最后一个是bcde
"abcdabcd" True 因为它是abcd重复2次构成
"xyz" False 因为它不是某一个String重复
"aaaaaaaaaa" False 重复的短String长度应至少为2(这里不能看做aa重复5次)
要求算法复杂度为O(n)
public boolean isMultiple(String s){
}
Ans:
用KMP吧。检查preprocess部分生产的array pai 就可以了。如果是valid case.
preprocessing array 必然满足下面的几个条件:
1. pai[n-1] 必须是最大值 (这个没必要专门检查,只要3满足就成);
2. s[0,...,n-pai[n-1])就是repeating pattern;
3. pai[n-1]/(length of the repeating pattern) >= 1;
4. pai[n-1] % (length of the repeating pattern) == 0.
bool isMultiple(const string &text){
int n=text.length();
vector<int> pai(n);
computeVec(text,pai);
int len=n-pai[n-1];
return len>1&&pai[n-1]/len>=1&&pai[n-1]%len==0;
}
void computeVec(const string &Pat, vector<int>&pai){//from KMP
pai[0]=0;
int k=0;
int m=Pat.length();
for(int i=1;i<m;i++){
while(k>0&&Pat[k]!=Pat[i])
k=pai[k-1];
if(Pat[k]==Pat[i])
k++;
pai[i]=k;
}
}
有一种String,是把一个更短的String重复n次而构成的,那个更短的String长度至少为
2,输入一个String写代码返回T或者F
例子:
"abcabcabc" Ture 因为它把abc重复3次构成
"bcdbcdbcde" False 最后一个是bcde
"abcdabcd" True 因为它是abcd重复2次构成
"xyz" False 因为它不是某一个String重复
"aaaaaaaaaa" False 重复的短String长度应至少为2(这里不能看做aa重复5次)
要求算法复杂度为O(n)
public boolean isMultiple(String s){
}
Ans:
用KMP吧。检查preprocess部分生产的array pai 就可以了。如果是valid case.
preprocessing array 必然满足下面的几个条件:
1. pai[n-1] 必须是最大值 (这个没必要专门检查,只要3满足就成);
2. s[0,...,n-pai[n-1])就是repeating pattern;
3. pai[n-1]/(length of the repeating pattern) >= 1;
4. pai[n-1] % (length of the repeating pattern) == 0.
bool isMultiple(const string &text){
int n=text.length();
vector<int> pai(n);
computeVec(text,pai);
int len=n-pai[n-1];
return len>1&&pai[n-1]/len>=1&&pai[n-1]%len==0;
}
void computeVec(const string &Pat, vector<int>&pai){//from KMP
pai[0]=0;
int k=0;
int m=Pat.length();
for(int i=1;i<m;i++){
while(k>0&&Pat[k]!=Pat[i])
k=pai[k-1];
if(Pat[k]==Pat[i])
k++;
pai[i]=k;
}
}
Tuesday, November 18, 2014
未名空间十大: G家面经总结,顺便求个bless,和一起找工作的同学们共勉
未名空间十大: G家面经总结,顺便求个bless,和一起找工作的同学们共勉: 发信人: freepooh (freepooh), 信区: JobHunting 标 题: G家面经总结,顺便求个bless,和一起找工作的同学们共勉 发信站: BBS 未名空间站 (Fri Apr 4 11:13:06 2014, 美东) 也找工作了一段时间了,从...
kmp string match
from CLRS(Introduction to Algorithm)
For a pattern P, pai[q] is the length of the longest prefix of P that is a proper suffix of Pq. (Pq is P[1...q], note that here the index start from 1, which is different from the code below)
vector<int> computepai(string Pat){
int n=Pat.length();
vector<int> pai(n,0);
pai[0]=0;
for(int i=1;i<n;i++){
int k=pai[i-1];//number of characters matched
while(k>0&&Pat[k]!=Pat[i])
k=pai[k-1];
k+=Pat[k]==Pat[i];
pai[i]=k;
}
return pai;
}
下面这个computepai是算法导论上的版本,和上面的几乎一样(不同的只是k的位置),但是上面的似乎更容易理解和记忆些。
vector<int> computepai(string Pat){
int n=Pat.length();
vector<int> pai(n,0);
pai[0]=0;
int k=0;//number of characters matched
for(int i=1;i<n;i++){
while(k>0&&Pat[k]!=Pat[i])
k=pai[k-1];
if(Pat[k]==Pat[i])
k++;
pai[i]=k;
}
return pai;
}
void matchstr(string text,string Pat){
int n=text.length();
int m=Pat.length();
vector<int> pai= computepai(Pat);
int k=0;//number of characters matched
for(int i=0;i<n;i++){//scan the text from left to right
while(k>0&&Pat[k]!=text[i])
k=pai[k-1]; //next character of P doesn't match text[i]
if(Pat[k]==text[i])
k++; //next character matches
if(k==m){ // is all of P matched
cout<<"find in pos : "<<i-m+1<<" "<<text.substr(i-m+1,m)<<endl;
k=pai[k-1];
}
}
}
For a pattern P, pai[q] is the length of the longest prefix of P that is a proper suffix of Pq. (Pq is P[1...q], note that here the index start from 1, which is different from the code below)
vector<int> computepai(string Pat){
int n=Pat.length();
vector<int> pai(n,0);
pai[0]=0;
for(int i=1;i<n;i++){
int k=pai[i-1];//number of characters matched
while(k>0&&Pat[k]!=Pat[i])
k=pai[k-1];
k+=Pat[k]==Pat[i];
pai[i]=k;
}
return pai;
}
下面这个computepai是算法导论上的版本,和上面的几乎一样(不同的只是k的位置),但是上面的似乎更容易理解和记忆些。
vector<int> computepai(string Pat){
int n=Pat.length();
vector<int> pai(n,0);
pai[0]=0;
int k=0;//number of characters matched
for(int i=1;i<n;i++){
while(k>0&&Pat[k]!=Pat[i])
k=pai[k-1];
if(Pat[k]==Pat[i])
k++;
pai[i]=k;
}
return pai;
}
void matchstr(string text,string Pat){
int n=text.length();
int m=Pat.length();
vector<int> pai= computepai(Pat);
int k=0;//number of characters matched
for(int i=0;i<n;i++){//scan the text from left to right
while(k>0&&Pat[k]!=text[i])
k=pai[k-1]; //next character of P doesn't match text[i]
if(Pat[k]==text[i])
k++; //next character matches
if(k==m){ // is all of P matched
cout<<"find in pos : "<<i-m+1<<" "<<text.substr(i-m+1,m)<<endl;
k=pai[k-1];
}
}
}
Subscribe to:
Posts (Atom)