几道算法题

最近在面试的过程中,遇到了很多手写代码的情况,我是真的不会写算法题,但是常见的还是要总结一下。

1.快速排序

这个我觉得背也要背下来。。。

用递归的思想,分别排序index左边的数组和index右边的数组。

⚠️:随机数的生成

#define random(a,b) (rand()%(b-a+1)+a) 生成[a,b]区间内的整数

int Partition(int data[],int length,int start,int end){

    if (data == nullptr || length<=0||start<0||end>length) {

        cout<<"error input"<<endl;

}

    srand((unsigned)time(NULL));

    int index = random(start,end);

    swap(data[index], data[end]);

    int small = start-1;

    for (int i = start; i<end; i++) {

        if (data[i]<data[end]) {

            ++small;

            if (small != i) {

                swap(data[small], data[i]);

            }

        }

    }

    ++small;

    swap(data[small], data[end]);

    return  small;

}

void QuickSort(int data[],int length,int start, int end){

    if (start == end) {

        return;

    }

    int index = Partition(data, length, start, end);

    //对左边右边分别排序

    if (index>start) {

        QuickSort(data, length, start, index-1);

    }

    if (index<end) {

        QuickSort(data, length, index+1, end);

    }

}

2.求数组的全排列

首先我们明确全排列的概念,数组1,2,3的全排列就是123,132,213,231,312,321

也就是说就是把数组的后n-1个数全排列,然后再加上第一个数。

其实数组的全排列和字符串的全排列是一个思想:⚠️:如果不想用res然后打印res的话,也可以直接把num打印出来。

void permutationWithArray(vector> &res,vector&num,int index)

{

    if (index>=num.size()) {

        res.push_back(num);

        return;

    }

    for (int i = index; i<num.size(); i++) {

        swap(num[i], num[index]);

        permutationWithArray(res,num,index+1);

        swap(num[i], num[index]);

    }

}

这里有一个相同思路的问题,就是字符串的全排列。一个字符串char a[] = "abc";那么a现在是abc,*a = a,如果a+1之后*a = b;

字符串的全排列:

void permutation(char* c,char* index){

    if (*index == '\0') {

        cout<<c<<endl;

}else{

    for (char* pBegin = index; *pBegin!='\0'; pBegin++) {

        swap(*pBegin, *index);//把字符串的第一个元素和每一个元素交换

        permutation(c, index+1);

        swap(*pBegin, *index);

    }

  }

}


3.调整一个数组中元素的顺序,让什么样的数位于什么样的数前面

可以用两个指针,一个指向数组的头部,一个指向数组的尾部,然后遍历数组。如果不满足条件就交换两个指针指向的元素,知道两个指针相等,顺序调换完毕。

4.反转链表

反转链表的时候需要注意,在遍历链表的时候要存储当前节点,当前节点的前一个节点,和当前节点的下一个节点。在反转链表的时候要注意,不能让链表断掉。

ListNode* reverseLinkList(ListNode* root){

    //重点就是为了防止反转后的链表断裂,我们在遍历一个节点的时候要保留它自己,它的上一个节点和它的下一个节点。

    ListNode* pNode = root;

    ListNode* pReservedNode = nullptr;

    ListNode* pPrev = nullptr;

    while (pNode!=nullptr) {

        ListNode* pNext = pNode->next;

        if (pNext == nullptr) {

            pReservedNode = pNode;

        }

        pNode->next = pPrev;

        pPrev = pNode;

        pNode = pNext;

    }

    return pReservedNode;

}

5.利用partition算法还能做什么

求数组中出现次数超过一半的数。

一个数在数组中出线次数超过一半,那么它一定是排好序的数组的中位数,也就是说我们找到数组的中位数就找到了这个数,也就是找这个数组中第n/2大的数字,我们有时间复杂度为O(n)的算法来求数组中第k大的数字,就是用Partition函数。当index是n/2的时候arr[index]就是第n/2大的数啦。

求数组中最小的k个数。

如果index的下标是k,那么arr[index]前面的k个数就是数组中最小的k个数,可以用这种方法在O(n)复杂度内求出数组中最小的k个数。

6.在排序数组中查找数字出现的次数

因为一个数组是排序的,那么如果一个数字重复出现了多次在数组中肯定是连着的,也就是说我们找到一个数字在数组中第一次出现的位置,再找到他第二次出现的位置,两次出现的位置相减加1,就是数字出现的次数。

⚠️:在找数字第一次出现的位置的时候,不能找到数字出现的位置就完了,还要看这个数字前面的数字是不是也是要找的数字,如果前面的数字不是要找的数字或者前面没有数字了说明就是第一次出现的位置,如果不是这样的话就要继续在前面的数组里查找。

7.查找有序数组中没有出现的数

一个有序数组的长度是n,数组中所有的数字都在0~n-1的范围内,只有一个数字没有出现在这个数组中,想要把这个数字找出来。

因为数组是一个有序数组,可以用二分查找,找到数组的中间位置上的数,如果这个数和自己的下标不相等,说明它或者它的前面的数就是少的那个,如果它前面的数和自己的下标相等,说明中间这个数是第一个值和下标不等的元素,他的下标就是缺失的数字。

中间位置上的数和自己的下标相等,说明少的那个数出现在数组的后半部分。3

8.设计一个包含min函数的栈

首先让我们设计的数据结构是栈,就必须满足栈先进后出的特点,无论是出栈还是入栈都在栈顶进行。其次要包含min函数,就是说要让栈有一个功能就是在O(1)的时间复杂度内弹出栈中的最小元素。

我们可以设计一个辅助栈,每次有元素入栈的时候都和当前栈中的最小元素比较,把较小的那一个压入辅助栈,如果最小值被弹出了,辅助栈的栈顶元素也会被弹出,弹出后辅助栈中的栈顶元素就是当前栈中的最小值。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容