面试题系列之Google 1

这题出自2013年谷歌的校招笔试。题目是这样的:

长度为N的数组乱序放着0至N-1,现在只能进行0与其他元素的swap,请设计并实现排序。

读完题目,立马就有了一个简单的思路。既然是0至N-1存放在这个数组中,那么排序后的数组是0 1 2 3 .... ,也就是每个元素的值和它的下标是一致的。这给了我们一个投机取巧的机会。每个元素归为可以分为两步来归位。对于位置X,第一步 将此处的值 和 0进行交换。 第二步 将此处的值(此时为0) 和 值X进行交换。顺着这么一个简单的思路,我们可以先写出如下蠢爆了的代码(你可以直接跳过这段代码进行阅读,毕竟这种low代码没啥可读的,我写下只是为了记录自己思考的整个过程,写这种Low代码的好处大约是,这种代码low到不假思索,可以边写边思考,写的同时就可以考虑更优的方案了。而此代码稍加改进可能就会成为更优的方案,也不算浪费体力吧)

inline void swap(int *_arr,int _index1,int _index2)
{
    _arr[_index1] = (_arr[_index1] ^ _arr[_index2]);
    _arr[_index2] = (_arr[_index1] ^ _arr[_index2]);
    _arr[_index1] = (_arr[_index1] ^ _arr[_index2]);
}

int find(int *_arr,int _num)
{
    int ix = 0;
    while(_arr[ix] != _num)
        ix++;
    return ix;
}

void swap_sort(int *_arr,int _len)
{
    for(int ix=0;ix<_len;ix++)
    {
        int zero_index = find(_arr ,0);
        swap(_arr,ix,zero_index);
        int ix_index   = find(_arr ,ix);
        swap(_arr,ix,ix_index);
    }
}

这样一份代码也就初步将我们的想法实现了,其实不用写完,写一半时 '写出高效代码' 的觉悟就让我们敲不下去键盘了。这样的代码效率低到令人发指,最主要就是find这个函数似乎是没有必要的,我们要去记住每个元素的位置,而不是每次都要去寻找。于是我们在 swap_sort函数的开头添加如下三行代码

int *index_arr = new int[_len];
for(int ix=0;ix<_len;ix++)
  index_arr[_arr[ix]] = ix;

index_arr数组就是记录了每个数在_arr数组中所处的位置。
这样我们就不必每次找寻了。代码变成了下面的样子

  int *index_arr = new int[_len];
    for(int ix=0;ix<_len;ix++)
        index_arr[_arr[ix]] = ix;
    for(int ix=0;ix<_len;ix++)
    {
        swap(_arr,ix,index_arr[0]);
        swap(_arr,ix,index_arr[ix]);
    }

感觉哪里不对,我们不能犯了刻舟求剑的错误 水是流动的 我们的数组也是在变动的,自然记录元素位置的数组也要跟着变动。继续添加两行

int *index_arr = new int[_len];
    for(int ix=0;ix<_len;ix++)
        index_arr[_arr[ix]] = ix;
    for(int ix=0;ix<_len;ix++)
    {
        swap(_arr,ix,index_arr[0]);
        swap(index_arr,0,_arr[index_arr[0]]);

        swap(_arr,ix,index_arr[ix]);
        swap(index_arr,0,ix);
    }

这里需要注意 swap(index_arr,0,_arr[index_arr[0]]); 这句代码是我们交换了原数组中0和位于ix处值的位置(记为val_ix),那么我们自然要在记录位置的数组中反映。记录位置数组的变化是这样的:位置0记录了原数组中0所处的位置。位置val_ix记录了val_ix在原数组中的位置。我们也交换它们的内容。swap(index_arr,0,val_ix)即可。可是val_ix的值已经被我们交换了位置,所以我们要去它新的位置找它,也就是0原来所处的位置。
完整代码如下:

inline void swap(int *_arr,int _index1,int _index2)
{
    _arr[_index1] = (_arr[_index1] ^ _arr[_index2]);
    _arr[_index2] = (_arr[_index1] ^ _arr[_index2]);
    _arr[_index1] = (_arr[_index1] ^ _arr[_index2]);
}



void swap_sort(int *_arr,int _len)
{
    int *index_arr = new int[_len];
    for(int ix=0;ix<_len;ix++)
        index_arr[_arr[ix]] = ix;
    for(int ix=0;ix<_len;ix++)
    {
        swap(_arr,ix,index_arr[0]);
        swap(index_arr,0,_arr[index_arr[0]]);

        swap(_arr,ix,index_arr[ix]);
        swap(index_arr,0,ix);
    }
}
int main(int argc, const char * argv[]) {
    int test_arr[10] = {1,0,4,3,2,8,5,9,6,7};
    swap_sort(test_arr, 10);
    for_each(test_arr,test_arr+10,[](int num){cout << num << " ";});
    cout << endl;
    std::cout << "Hello, World!\n";
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,744评论 0 33
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,625评论 18 399
  • 《2014》(爱的摇篮曲) 从来没有离家远航的打算 只是躺在小舟上片刻假寐 顺着潮左右摇摆摇摆左右 全身都被日光晒...
    梅溪仙子阅读 368评论 0 0
  • 7月3日 星期一 晴转阵雨 今天我们家没水,晚上我们一家子去我们的新房子那边洗澡,我们房子还在装修,我和妹妹的...
    A叶瑞妹阅读 194评论 0 1
  • ――卿薄情轻聚散 吾痴心恨别离 身处尘世中, 亲情、友情、爱情诸多关系, 只因“利益”二字而变了质。 辗...
    初夏秋心阅读 248评论 0 0