我的数据结构1

(叠甲:如有侵权请联系,内容都是自己学习的总结,一定不全面,仅当互相交流(轻点骂)我也只是站在巨人肩膀上的一个小卡拉米,已老实,求放过)

时间复杂度:时间复杂度是指算法中基本操作的执行次数随输入规模 n 增长的渐近趋势。它不关心算法在特定硬件上的实际运行秒数(受 CPU、编程语言、编译器等影响),只关注算法本身的效率随数据量变大的增长规律。

空间复杂度:空间复杂度是指算法在运行过程中所需的额外内存空间随输入规模 n 增长的渐近趋势

题一:数组nums包含从0n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?

题目分析:该题实测了两种解题思路

第一种:使用计数排序的思路从而找出缺失的数,但这样的空间复杂度是O(N),因为要遍历数组,时间复杂度也是O(N);

cpp 复制代码
int missingNumber(int* nums, int numsSize)
{
    int* a = malloc(sizeof(int)*(numsSize+1));
//这里不要使用int a[numsize+1] = {0}的变长数组,只有少数编译器支持;
    memset(a,0,sizeof(int)*(numsSize+1));
//这一步非常关键,如果没有初始化数组的话,可能会有些脏数据影响输出;
    for(int i = 0;i<numsSize;i++)
    {
        a[nums[i]]++;
    }
    for(int j = 0;j<=numsSize;j++)
    {
        if(!a[j])
        {
            free(a);
            return j;
        }
    }
    free(a);
    return -1;
}

第二种:遍历数组求和,再依次减去原数组的值,这种方法的时间复杂度依旧是O(N),但是空间复杂度却来到了O(1);

cpp 复制代码
int missingNumber(int* nums, int numsSize)
{
    int sum = 0;
    for(int i = 0;i<=numsSize;i++)
    {
        sum = sum +i;
    }
    for(int j = 0;j<numsSize;j++)
    {
        sum = sum-nums[j];
    }
    return sum;
}

题目二:整数数组 sockets 记录了一个袜子礼盒的颜色分布情况,其中 sockets[i] 表示该袜子的颜色编号。礼盒中除了一款撞色搭配的袜子,每种颜色的袜子均有两只。请设计一个程序,在时间复杂度 O(n),空间复杂度O(1) 内找到这双撞色搭配袜子的两个颜色编号。

题目分析:该题要求空间复杂度为O(1),计数排序就行不通了,使用位运算的异或运算以及与运算比较合适;首先将数组的数据全部进行异或(^)操作,得到一个值a,再将该值与取负(原码取反+1),得到(-a),将a与(-a)进行与(&)运算得到key值,key值就意味着该组数据中可以从右往左边数第几位为1,在使用key值作为分组的桥梁,是的同一组内的不同值再进行一次异或(^)操作,最后留下来的数就是需要的答案了;

cpp 复制代码
int* sockCollocation(int* sockets, int socketsSize, int* returnSize) 
{
    int a = 0;
    //用于存放最初的异或值
    for(int i =0;i<socketsSize;i++)
    {
        a = a^sockets[i];
    }
    int key = a&(-a);
    //计算key值桥梁
    int num1 = 0;
    int num2 = 0;
    for(int j = 0;j<socketsSize;j++)
    {
        if(sockets[j]&key)
    //进行分组
        {
            num1 = num1^sockets[j];
        }
        else
        {
            num2 = num2^sockets[j];
        }
    }
    int* result = malloc(2*sizeof(int));
    //开辟存储结果的数组;
    result[0] = num1;
    result[1] = num2;
    *returnSize = 2;
    //确认结果数组的长度
    return result;
}

注意:函数头部的int* returnSize是一个整数,而且是返回数组的长度,并不是一个数组。