2015.03.最新面试题(1)

来源:互联网 发布:极乐净土动作数据下载 编辑:程序博客网 时间:2024/06/11 01:45
Q1: 给出列表:
1: a, b
2: b, c
3: e
4: a

...


合并有相同字符的列表. 输出:
(1, 2, 4) (a, b, c)

(3) (e)


分析: 这道题思路很简单,就是用按照顺序合并,对于每一个列表的row,检查是否能和以前的值合并. 

但是要格外注意的是,每个输入的row可能同时与前几个值都可以合并,只是要把它们全部合并在一起.

C++实现如下:

class MySet{  vector<string> roots_;  unordered_set<string> values_;public:  MySet(const string& s){    makeSet(s);  }  void makeSet(const string& s){    int start = 0;    int end = s.find(':');    roots_.push_back(s.substr(start, end-start));    start = end+1;    end = s.find(',', start);    while(end!=string::npos){      values_.insert(s.substr(start, end-start));      start = end+1;      end = s.find(',', start);    }    values_.insert(s.substr(start, s.size()-start));      }    bool joinable(const MySet& other){    unordered_set<string>::const_iterator it;    for(it=other.values_.begin(); it!=other.values_.end();++it){      if(values_.count(*it)) return true;          }    return false;  }    void join(const MySet& other){    for(int i=0; i<other.roots_.size(); ++i){      roots_.push_back(other.roots_[i]);    }    unordered_set<string>::const_iterator it;    for(it=other.values_.begin(); it!=other.values_.end();++it){      values_.insert(*it);    }  }    void print(){    cout << "(" << roots_[0];    for(int i=1; i<roots_.size(); ++i){      cout << "," << roots_[i];    }    cout << ")";    unordered_set<string>::iterator it;    it = values_.begin();    cout << "(" << *it;    ++it;    for(; it!=values_.end(); ++it){      cout << "," << *it;    }    cout << ")" << endl;  }};void combine_rows(const vector<string>& table){  if(table.empty()) return;  typedef list<MySet>::iterator Iter;  list<MySet> result;  result.emplace_back(table[0]);  for(int i=1; i<table.size(); ++i){    MySet temp(table[i]);    //    temp.print();    vector<Iter> joinable_list;    for(Iter it=result.begin(); it!=result.end(); ++it)      {if(it->joinable(temp)){  joinable_list.push_back(it);}      }        result.push_front(temp);        for(int j=0; j<joinable_list.size(); ++j){      result.front().join(*(joinable_list[j]));      result.erase(joinable_list[j]);    }      }  for(Iter it=result.begin(); it!=result.end(); ++it){    it->print();  }  }


Q2. 写一个random函数,产生0 ~ n-1的数,但是有一个black list,产生的数不能在black 
list里。 bl是sorted的。
int myRandom(int n, vector<int> bl)
{
    //.....
}. 
时间复杂度log(n)

分析:  这道题用mapping非常trivial, 而且有disadvantage. 譬如blacklist里面有几百万个数怎么办?几百万个数就是~400MB,超过了CPU的
缓存的大小。如果建hash table,性能会损失非常大。正确的解法是用binary search. 

C++实现如下:

int random(int n, const vector<int>& bl){  if(n==bl.size()) return -1;  int r = rand()%(n-bl.size());  if (bl.size()==0 || r<bl[0]) return r;    cout << r << " : ";  int offset = r - bl[0] + 1;    int left = 0, right=bl.size()-1;  while (left+1 < right) {    int m = (left + right) / 2;    cout << bl[left]+offset << ", ";    // number of non black list numbers on left    int available_nums = (bl[m] - bl[left]) - (m - left);    if (available_nums < offset) {      offset -= available_nums;      left = m;    } else {      right = m;    }  }    if (offset > (bl[right] - bl[left]) - (right - left)) {    offset++;  }    return bl[left] + offset;}


 


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 戴尔游匣5577开机黑屏怎么办 三星s6的通知栏拉不下来怎么办 电脑记住密码打不开了怎么办 联想手机升级系统失败了怎么办 日本语言学校申请研究生签证怎么办 在埃塞俄比亚签证过期了怎么办 看完的小说想要卖掉该怎么办 在俄罗斯脸干了痛怎么办 苹果手表电池放亏了怎么办 平板电脑电池不耐用怎么办 计算机电池放入后没反应怎么办 笔记本电脑玩游戏花屏怎么办 笔记本玩游戏花屏怎么办 笔记本电脑充电插口坏了怎么办 车蓄电池没电了怎么办 汤浅q85电瓶亏电怎么办 富士康自离行李怎么办 微店红酒食品认证怎么办 yy频道提示禁止游客进入怎么办 口红颜色太艳了怎么办 我在菲律宾想走怎么办 当国家流通货币不够用怎么办 苹果5s账号密码忘记怎么办 钢铁雄心3补给不足怎么办 灯外观颜色太难看了怎么办 被移民公司骗了怎么办 文明5大包锁区怎么办 鸭子被黄鼠狼叼走了怎么办 黄鼠狼再店了拉屎怎么办 我只有信用卡但是又想去嫖怎么办 瑞士退税单掉了怎么办 装了新风噪音大怎么办 意大利 护照被偷了怎么办 请问去意大利要怎么办护照 在意大利护照丢了怎么办 考研二战档案打回原籍怎么办 脸上的肉往下掉怎么办 眼镜带了往下掉怎么办 孩子捅别的孩子眼睛了怎么办 眼睛不小心捅伤怎么办 我的爸爸是小偷怎么办