复试准备

数组

常见题目

把两个排序好的数组合并成一个排序好的数组

解法:双指针,先判断越界,然后比较的时候要注意维持稳定性。把几种情况合并来写。

int Merge(int *a, int na, int *b, int nb, int *c) {
    int pa = 0, pb = 0, pc = 0;
    while(pa < na || pb < nb) {
        if(pa == na || (pb < nb && a[pa] > b[pb])) {
            c[pc] = b[pb];
            ++pc;
            ++pb;
            continue;
        } else {
            c[pc] = a[pa];
            ++pc;
            ++pa;
            continue;
        }
    }
    return pc;
}

把数组中的负数都移动到正数的前面,不改变负数之间的顺序和正数之间的顺序

解法:假如可以改变顺序,就像第k大一样去调整0的位置就可以了,但是这里不允许改变顺序,简单的方法有两种,一种是时间O(n^2),空间O(1)的插入排序,另一种是复制一遍的时间O(n),空间O(n)的归并排序。

有一种比较花里胡哨的方法,当值域小于int表示范围的sqrt的时候可以弄。

1.扫描一次数组,数出有多少个正数以及有多少个负数,同时求出最大值和最小值。

2.判断全正数或者全负数的情况。

3.把每个数减去最小值(保证最小值是负数),然后加上值域范围M=max-min+1。使得每个数变成非负数,并且乘以M(使用M进制数的高位记录这个数原本的信息)。

4.分别生成正数指针和负数指针,指向他们应该去的第一个位置。

5.扫描一次数组,把每个数原本的信息还原出来,记录在该去的指针指向的位置的低位

6.扫描一次数组,把高位丢掉(模M),把低位加上最小值(保证最小值是负数)。

启示:可以利用数组中元素的值域,强行生成出空间,方法是分成高位低位记录,本质上和用两个short进行归并差不多,不过非常巧妙。

void Solve(int *a, int n) {
    int cntn = 0, mina = 0, maxa = 0;
    for(int i = 0; i < n; ++i) {
        if(a[i] < 0) {
            ++cntn;
            if(a[i] < mina)
                mina = a[i];
        } else {
            if(a[i] > maxa)
                maxa = a[i];
        }
    }
    int M = maxa - mina + 1;
    for(int i = 0; i < n; ++i) {
        a[i] -= mina;
        a[i] *= M;
    }
    int pn = 0, pp = cntn;
    for(int i = 0; i < n; ++i) {
        if(a[i] < (0 - mina)*M) {
            a[pn] += a[i] / M;
            ++pn;
        } else {
            a[pp] += a[i] / M;
            ++pp;
        }
    }
    for(int i = 0; i < n; ++i) {
        a[i] %= M;
        a[i] += mina;
    }
    return;
}

链表

翻转链表

https://leetcode-cn.com/problems/reverse-linked-list/submissions/

非常简单,保存一下cur_next=cur->next,然后把cur->next=revHead,再revHead=cur,最后cur=cur_next。其实发现这四个构成一个循环。

简单介绍一下栈

栈是一种先进后出的数据结构,必须要实现的接口为:Push,Pop,Top。

面向对象的栈

class Stack {
private:
    int *data;
    int maxSize;
    int top;
public:
    Stack(int maxSize): maxSize(maxSize) {
        data = new int [maxSize + 1];
        top = 0;
        return;
    }

    void Clear() {
        top = 0;
        return;
    }

    int Size() {
        return top;
    }

    int Top() {
        if(top == 0)
            exit(-1);
        return data[top];
    }

    void Push(int value) {
        if(top == maxSize)
            exit(-1);
        ++top;
        data[top] = value;
        return;
    }

    void Pop() {
        if(top == 0)
            exit(-1);
        --top;
        return;
    }
};

参考资料

代码面试需要知道的8种数据结构(附面试题及答案链接) - Fundebug - 博客园

面试必刷-《剑指offer》刷题小结 - 简书

原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12608614.html