顺序表相关OJ题练习——移除链表和合并两个有序数组

        前面我们已经学习了时间复杂度、空间复杂度以及顺序表的接口实现,现在我们来做两道OJ题巩固一下吧!

一、移除链表

 

 思路一:找到一次val就挪动数据进行覆盖删除,那么这个思路的时间复杂度和空间复杂度是多少呢?

int removeElement(int* nums, int numsSize, int val){
    int cnt = 0;
    for(int i=0; i<numsSize; i++)
    {
        if(nums[i] == val)
        {
            for(int j=i; j<numsSize-1; j++)
            {
                nums[j] = nums[j+1];
            }
            numsSize--;
            i--;
        }
    }
    return numsSize;
}

        通过观察代码,我们可以发现这个思路的时间复杂度为O(N^2),空间复杂度为O(1)。虽然满足了空间复杂度为O(1)条件,但时间复杂度较大。

思路二:开辟一个同样大小的数组tmp,把不是val的数据放到tmp,再把tmp中的数据拷贝回来。请思考一下这个思路的时间复杂度和空间复杂度是多少呢?

int removeElement(int* nums, int numsSize, int val){
    int* tmp = (int*)malloc(sizeof(int)*numsSize);
    int j = 0;
    for(int i=0; i<numsSize; i++)
    {
        if(nums[i] != val)
        {
            tmp[j] = nums[i];
            j++;
        }
    }
    for(int i=0; i<numsSize; i++)
    {
        nums[i] = tmp[i];
    }
    return j;
}

        通过观察代码,我们可以发现这个思路的时间复杂度为O(N),空间复杂度也为O(N)。相较于思路一,虽然时间复杂度减小了,但空间复杂度增大了。那么有什么方法可以让时间复杂度为O(N),空间复杂度为O(1)呢?

思路三:在思路二的基础上,不开辟额外的数组tmp,src去找nums数组中不等于val的值,放到dst指向的位置上去,再src++,dst++。

int removeElement(int* nums, int numsSize, int val){
    int i=0;
    while(i < numsSize)
    {
        if(nums[i] == val)
        {
            int j=i+1;
            while(j < numsSize)
            {
                nums[j-1] = nums[j];
                j++;
            }
            numsSize--;
            i--;
        }
        i++;
    }
    return numsSize;
}

       通过观察代码,我们可以发现这个思路的时间复杂度为O(N),空间复杂度为O(1),满足了我们更高的要求。

二、合并两个有序数组

 思路一:将nums2中的数据拷贝到nums1中,再进行排序。那么这个思路的时间复杂度和空间复杂度是多少呢?

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int i=m;
    int j=0;
    //将nums2中的数据拷贝到nums1中
    while(i<m+n)
    {
        nums1[i++] = nums2[j++];
    }
    //排序
    for(i=0; i<m+n-1; i++)
    {
        for(j=0; j<m+n-1-i; j++)
        {
            if(nums1[j] > nums1[j+1])
            {
                int tmp = nums1[j];
                nums1[j] = nums1[j+1];
                nums1[j+1] = tmp;
            }
        }
    }
}

        现在来公布正确答案:时间复杂度为O(N^2),空间复杂度为O(1),你计算对了吗?

思路二:从后开始比较nums1[end1]与nums2[end2]的大小,将大的数据赋值给nums1[end],再end--,end1--(或end2--)。(end1=m-1,end2=n-1,end=m+n-1)

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int end1 = m-1;
    int end2 = n-1;
    int end = m+n-1;
    //若end2先小于0的情况
    while(end1>=0 && end2>=0)
    {
        if(nums1[end1] > nums2[end2])
        {
            nums1[end--] = nums1[end1--];
        }
        else
        {
            nums1[end--] = nums2[end2--];
        }
    }
    //若end1先小于0的情况
    while(end2>=0)
    {
        nums1[end--] = nums2[end2--];
    }
}

        这种思路的时间复杂度为O(N),空间复杂度为O(1)。你想到了吗?

本篇文章的内容到这里就结束了,感谢各位的观看,希望大家都能有所收获!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值