数据结构初阶——复杂度OJ练习题

第一题

数据结构初阶——复杂度OJ练习题_第1张图片

对于该题,最能想到应该有四种方法:

1. 排序

可以将元素排序好,再遍历一遍数组看后一个是否是前一个元素的值+1,但是从对于初学者掌握的无非就是冒泡排序或者qsort

很遗憾,虽然但是,不满足题目的时间复杂为O(n),因为冒泡排序的时间复杂度为O(n^2),qsort的时间复杂度为O(nlogn)因此,因此不行

2. 映射

开辟一个数组并初始化为-1(因为有0的存在),把对应的数字放入对应的数组下标所对应的数组元素中,然后再遍历一遍数组,出现负数的那个元素则为缺少的数字

很遗憾,虽然但是,要使用数组开辟空间,空间复杂度为O(n),因此不行

3. 使用操作符 ^

使用异或操作符,利用它的两个特性,同样的数字异或以后为0,不论顺序,一个数字与0异或为本身,空间复杂度O(1),时间复杂度为O(n)

所以可以!附上代码

int missingNumber(int* nums, int numsSize) {
    int i = 0;
    int temp = 0;

    //先和数组异或
    for (i = 0; i < numsSize; i++)
    {
        temp ^= nums[i];
    }

    //再和0~n的数字异或,就得到缺少的数字
    for (i = 0; i <= numsSize; i++)
    {
        temp ^= i;
    }

    return temp;
}

4. 等差数列

因为是0~n的数字,因此,这是一个等差数列,所以先把0~n的数字求和,再减去数组中的所有元素,剩下的数字即为所缺数字,时间复杂为O(n),空间复杂度为O(1),因此可行,附上代码

int missingNumber(int* nums, int numsSize) {
    int i = 0;
    //等差数列求和
    int Sn = ((0 + (numsSize)) * (numsSize + 1)) / 2;
    //减去数组中的每个值,即剩下的就是缺少值
    for (i = 0; i < numsSize; i++)
    {
        Sn -= nums[i];
    }
    return Sn;
}

第二题

数据结构初阶——复杂度OJ练习题_第2张图片

 题目要求至少三种方法,这道题最容易能想到能想到两种,第三种不太好想到

1. 右旋k次,依次移一个

先把数组最后一个元素先给放到一个临时变量temp中,然后将数组中的元素从第一个开始依次往后赋值,最后将temp中的值赋给第一个元素,即完成了一次的右旋,右旋k次即按这个思路进行k次

这个方法的空间复杂度是O(1), 但是,时间复杂度是O(n*k),为什么是k呢?

因为这种情况最好的结果是k=1,但是最坏的结果却是要旋转n-1次(k % N = N - 1),也就是说,时间复杂度最差能到O(n^2),受k影响过大,所以用k最好

很遗憾,虽然但是,这种方法leetcode不给过,时间超出限制,时间复杂度太差!

2. 额外开数组

开过个数组,然后把k个元素放过去,很简单

很遗憾,虽然但是,空间复杂度和时间复杂度都是O(n),不满足要求!

3. 逆置三次

前N~K个元素逆置,后K个逆置,然后整体逆置

时间复杂度为O(n),空间复杂度为O(1),满足

代码如下

void reverse(int* nums, int left, int right)
{
    while(left < right)
    {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
        ++left;
        --right;
    }
}


void rotate(int* nums, int numsSize, int k){
    //防越界
    k %= numsSize;
    //前面部分逆置
    reverse(nums, 0, numsSize-k-1);
    //后面部分逆置
    reverse(nums, numsSize-k, numsSize-1);
    //全部逆置
    reverse(nums, 0, numsSize-1);
}

你可能感兴趣的:(#,初级数据结构,#,练习题,#,C语言,数据结构,c语言)