前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >顺序表习题详解(超详细)

顺序表习题详解(超详细)

作者头像
用户11295429
发布2024-10-16 17:01:19
690
发布2024-10-16 17:01:19
举报
文章被收录于专栏:王的博客专栏

前言:

在写完链表习题1的时候,我突然回想起我之前也写过顺序表的习题,结果我看了一遍习题以后,我发现我大多数都忘记了,所以为了巩固知识点,于是诞生了这一篇文章(结果这一篇文章我搁置了一个月才写的,暑假光玩了),下面进入今天的刷题之旅喽!

正文:

1.移除元素

还是老规矩,我先给各位读者朋友展示一下这个题目:27. 移除元素 - 力扣(LeetCode)

在讲这个题目之前,小编先多嘴一下,我建议各位读者朋友在学完一些知识点以后,一定要记得在自己去巩固一下知识点,小编当初就是光学没复习,导致现在很多知识点忘记了,那种知识明明了解过但是脑子就是记不清了的感觉真的很难受,所以各位一定要温故知新!题外话就不多说了,下面小编开始讲解这个题目。

但看这个题目,可能很多读者朋友都有着自己的见解,小编当初拿到这个题的时候,就联想到了前面学习的顺序表的内容,小编当时想先写一份顺序表,然后通过顺序表里面的指定位置删除的方法,这样我们就可以完成移除元素操作了,但是这种方法是比较消耗时间的,而且代码量还很大,一不注意就可能会写错,所以小编在听完老师的讲解以后,就知道了这个题更为简单,更nb的算法,下面小编就给出这个题目的比较牛的思路

首先,我们可以先设置好两个变量src和del,这两个变量的作用是通过和数组的配合作为一个指针,小编通过上面的给出的例子来搭配图文讲解:

我们来说一下它们各自的作用,我们可以把src看做成一个探路的,让src代表的数组值和给定的的值进行比较,看他们是否相等,如果相等的话,直接让src往后走,del按兵不动,直到nums[src] != nums[del]的时候,我们先把arr[src]的数据赋值给arr[del],之后再让del,src都往后走一步,因为此时del代表的数组的值和给定的值是相等的,所以我们需要让src找到和给定的值不同的数,此时我们就可以完成一次的数的消除,之后我们在采用循环的知识点,循环的条件自然是跑的最快的src不会超过数组的大小,此时我们就完成了元素的移除操作,下面小编通过图文的方式给大家展示这个思路:

从头开始看,刚开始的src代表的数组的值是3,此时我们想要删除的值就是3,所以此时我们可以让src往后走就可以了,如下图所示:

之后再让src代表的值和val比较,此时不相等,所以此时我们就可以把src的值给del,然后让他俩一起往后走就好了,此时我们就巧妙的把那个想要删除的元素“删除”(其实是覆盖了),结果如下图所示:

之后我们在往后找,此时src的内容和指定元素不相等,此时我们依旧进行那个流程:把src赋值给del,然后一起往后走,由于此时的值是一样的,所以小编就不在继续画图了,之后我们让src继续和val比较,此时由于相等,所以让src往后走就好了,这样的话src就已经跳出数组的范围了,此时我们循环结束,这样我们便完成了元素的移除,可能很多读者朋友认为此时我们并没有完成移除操作,因为此时nums里面的值还是四个,其实这个题目我们通过题干就可以知道,此时我们返回的数据个数,就是返回nums里面的元素个数,就拿上面的例子来说,我们可以直接返回del的值,此时返回的是2,所以我们此时就返回nums里面的2,2,正好达成了这个题目想让我们做的,所以我们就完成了这个题目!下面小编给大家源码:

代码语言:javascript
复制
int removeElement(int* nums, int numsSize, int val) {
    int src = 0,del = 0;
    while(src < numsSize)
    {
        if(nums[src] != val)
        {
            nums[del] = nums[src];
            del++;
        }
        src++;
    }
    return del;
}

这个题目小编最后也有话说,其实小编在重新写这个题目的时候,我也是忘记了这个题目的解法,我还是重新看了看视频我才知道这个题目的写法,可能我对这个题目的讲解有一些错误,希望各位读者朋友可以在评论区给我指出,废话不多说,下面进入下一个题的讲解!

2.删除有序数组的重复项

老规矩,小编先给各位题目:26. 删除有序数组中的重复项 - 力扣(LeetCode)

这个题目看起来,可能很多读者朋友就会想到还是可以使用顺序表去做完这个题目,小编当初就是这么想的,我想到顺序表我写过一个函数,上面我也说过,删除指定数据的函数便可以实现这个操作,此时我们也需要用到循环,还是和上面一样,这么做是很复杂的,是很耗时间的,所以小编在听完老师的讲解以后,知道了一个不错的方法,下面直接讲解:

此时我们还是用到了我们上一个题目的两个老朋友,src和del,此时src和del都先是0,即它俩所代表的是数组首元素,此时我们可以通过比较src和del所代表的元素的大小,如果相等的话,我们就让探路者src继续往后走,继续比较,如果不相等的话,此时的话我们就让del往后走,然后把src的值赋值给del,然后让src继续往后做,所以这里我们还是要用循环,这么操作是为了实现重复元素的删除,因为当del和src的值是一样的时候,说明此时重复或者是二者就是指向同一个位置,我们需要让src继续往后找,直到找到不同的时候,此时我们就可以让del往后走了,然后把src1的值给del,此时我们就完成了重复元素的覆盖,并且通过题干我们可以知道,此时我们返回唯一元素的数量就好了!下面小编通过图文并用示例一进行解释:

首先,我们可以先确定src和del的位置,之后我们进行第一次的比较,此时由于两者相等,所以数值肯定是一样的,我们直接让src往后走,如下图所示:

之后,我们继续进行比较,此时src和del依旧相等,所以我们继续让src往后走:

之后,我们继续进行比较,我们发现此时src和del不相等,所以我们就可以先让del往后走,然后让src的值赋给del,之后src往后走,这个循环的循环条件肯定是src不超过数组元素的个数,所以此时我们跳出了循环,证明我们删除了有序数组中的重复项了:

此时我们就完成了这个题目的讲解,下面小编给出这个题目的源代码:

代码语言:javascript
复制
int removeDuplicates(int* nums, int numsSize) {
    int src = 0,det = 0;
    while(src < numsSize)
    {
        if(nums[src] == nums[det])
        {
            src++;
        }
        else
        {
            det++;
            nums[det] = nums[src];
            src++;
        }
    }
    return det+ 1;
}

3.合并两个有序数组

老规矩,小编先给各位读者朋友中这个题目:88. 合并两个有序数组 - 力扣(LeetCode)

这个题目乍一看,可能很多读者朋友觉着这个题目是非常的困难,但是看到力扣给到这个题目的难度是简单,就觉着自己能力不行,小编这里想说,这么想是不对的,简单题也有难度之分,小编认为这个题目算是比较难的题目了,至少我当初对这个题目也没有什么好的思路,但是听完老师讲解以后,我觉着这个题目其实也还行,不过小编在写到这里的时候,突然又想到另一种做法,这里先说一下,我认为我们可以通过在动态开辟出一个新的数组来解决这个题目,我们通过循环,先比较出小的元素放入新的数组中,然后当循环结束以后,我们再把还有元素的数组直接放入到这个新数组的后面,然后让把新数组给予nums1就好了,小编认为这么做是可取的,各位读者朋友可以在看完着篇博客后试一试这个方法,小编先把博客写完在进行尝试,但这样做的话会让空间复杂度高一些,和小编老师讲解的方法相比复杂一些,下面小编先把这个方法讲解一下:

在刚开始,我们可以先设置好几个变量,分别是src,a,b,其中,src表示nums1最后一个元素的位置,a代表着nums1最后一个有效元素,b表示nums2最后一个元素,这个题的方法就是我们倒着来去比较a和b最后一个有效元素的大小,把大的放在nums最后一个元素的位置,然后让相应的位置--往前走,所以此时我们需要用到循环的知识,可能很多读者朋友会认为循环的条件就是a和b其中一个>=就好了,这么写是错误的,因为我们无法确保a和b谁先小于0,所以循环的条件应该是a>=0&&b>=0,此时就可以确保其中一个必然小于0,之后我们在通过循环的方式,把那个没有<0的变量经过循环以后直接从后往前放到nums1中,此时我们就可以实现两个有序的数组合并,通过文字说明可能很多读者朋友不清楚我表达的意思,下面小编通过图文以及上面的例子进行讲解:

首先,我们先把变量设置好,设置完以后就成下面这样了:

下面我们就开始进行比较了,我们先把a和b对应着的元素进行比较,此时不难看出b代表的元素比较大,我们把b代表的元赋给src,之后让src和b往前走,如下图所示:

之后我们经过不断的循环,继续判断a和b代表元素的大小,最后不难看出会是b<0结束这个循环,中间的过程小编就不展示了,这样就显的我在水字数,下面是经历完第一次循环的图:

此时我们已经结束了循环,但是这个题还没做完,因为a还小于0,所以针对于这种情况,我们通过if语言来判断谁大于0,然后我们让其继续从后往前循环,循环的条件就是对应的a或b>=0,这样的话我们就完成了合并操作,最后会形成下图:

下面小编给大家展示一下这个题目完成的代码:

代码语言:javascript
复制
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    int src = m+ n - 1,a = m - 1,b = n - 1;
    while(a >= 0 && b >= 0)
    {
        if(nums1[a] > nums2[b])
        {
            nums1[src--] = nums1[a--]; 
        }
        else
        {
            nums1[src--] = nums2[b--];
        }
    }
    if(a >= 0)
    {
        while(a >= 0)
        {
            nums1[src--] = nums1[a--];
        }
    }
    if(b >= 0)
    {
        while(b>=0)
        {
            nums1[src--] = nums2[b--];
        }
    }
}

4.总结

此时小编就完成全部习题的讲解,正如上面所说,我在过了一个多月后在看这些习题以后,也是全部忘了这些题目的解法,我后悔暑假的我在最后十几天一直在疯狂的玩,这一玩让我对于大部分数据结构的知识有点模糊了,现在小编也是开学了,小编决定开学以后重新拾取这些记忆碎片,我也会通过写博客的方式记录我复习的结果,如果本文章存在错误的话,请各位读者朋友在评论区指出,小编会及时的回复并改正错误的,那么,我们下一篇博客见啦!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.移除元素
  • 2.删除有序数组的重复项
  • 3.合并两个有序数组
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档