【数据结构】链表OJ题(顺序表)(C语言实现)

2024-04-14 1342阅读

【数据结构】链表OJ题(顺序表)(C语言实现)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿

🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟

🌟🌟 追风赶月莫停留 🌟🌟

🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀

🌟🌟 平芜尽处是春山🌟🌟

🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟

🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅

📝数据结构OJ题

  • ✏️移除元素
  • ✏️ 删除重复项
  • ✏️ 合并两个数组

    ✏️移除元素

    【数据结构】链表OJ题(顺序表)(C语言实现)

    题目链接:原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)

    我在这里给大家提供了常规的三种解法,第一种解法是错误示范

    解法一:大家首先肯定想到的是边遍历边删除,当然这也是常用的方法,但是实际上这个解法一是错误的

    int removeElement(int* nums, int numsSize, int val)
    {
        for (int i = 0; i  
    

    大家可以看到在这里我用到了两次for循环进行遍历和删除而且是一模一样的,大家可以看下面的图:【数据结构】链表OJ题(顺序表)(C语言实现)

    会出现两个相邻的数是一样的,如果你把前面的那个9去除了,那么后面那个9就会移到前面那个数的位置,而此时那个位置已经检查过了,所以第二个9就没发删除,就会遗留下来:

    【数据结构】链表OJ题(顺序表)(C语言实现)

    所以这里就采用两次循环就可以解决,但是问题来了,如果是三个相邻的数相同,是不是就得用三个for循环,那如果是四个,五个呢,所以该解法错误的原因在这里。当然你也可以先找到最多有几个相同并且相邻的数的次数,然后再用for循环当然这也可以,但是太复杂了,大家还是看看解法二。

    解法二:该解法用了指针

    int removeElement(int* nums, int numsSize, int val)
    {
        int* ret = nums;//重新定义一个新的数组空间
        int sum = 0;
        while (numsSize)
        {
            if (*nums != val)
            {
                *ret++ = *nums++;   //把不同的数移到新的数组空间中
                sum++;                     //记录新数组的长度
            }
            else
            {
                nums++;
            }
            numsSize--;
        }
        return sum;
    }
    

    解法二是利用了指针,解法才变得简单起来。

    解法三:用了两个变量

    int removeElement(int* nums, int numsSize, int val) {
        int right = 0 ;
        int left  = 0 ;
        for (int i = 0; i  
     
     

    在这里也是利用两个变量相互移动及赋值,不过这种解法教于指针更容易理解。

    ✏️ 删除重复项

    【数据结构】链表OJ题(顺序表)(C语言实现)

    题目链接: 删除排序数组中的重复项

    解法:

    int removeDuplicates(int* nums, int numsSize) {
        int left = 0 ;
        int right = 0 ;
        for(int i = 0; i  
     
     

    在这里还是利用了两个变量来记录数组元素的变化及移动,和上一题的解法三还是挺类似的,不过还是有一点差别。因为上一题我们是先赋值再移动,而这一题我们是先移动再赋值。为什么第二题就要先移动再赋值呢,这是因为我们这里是要保留一个,删除重复的,而第一题是直接删除。

    ✏️ 合并两个数组

    【数据结构】链表OJ题(顺序表)(C语言实现)

    题目链接: 合并两个有序数组

    解法:

    void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
         int m1 = m - 1 ;
         int n1 = n - 1 ;
         int sum = m + n - 1 ;
         while(m1>=0 && n1>=0)
         {
             if (nums1[m1] > nums2[n1])
             {
                 nums1[sum] = nums1[m1] ;
                 m1--;
                 sum--;
             }
             else
             {
                 nums1[sum] = nums2[n1] ;
                n1--;
                sum--;
             }
         }
         while(n1>=0)
         {
             nums1[sum] = nums2[n1] ;
             n1--;
             sum--;
         }
    }
    

    首先这一题无论是初始的两个数组还是后面合并的数组都是要求数据以递增的形式呈现。

    【数据结构】链表OJ题(顺序表)(C语言实现)

    上幅图中就是题目所给的两个有序数组和一些条件。

    按照题目意思我们只能从后面把数据填进去,如果从前面会覆盖一些数据,造成数据丢失。

    利用遍历来做,因为题目要求数据是递增的形式。所以只能利用遍历,一边遍历一边比大小。

    在这里又要分两种情况:

    第一种:n1还有剩余,m1已经分配完了,如下图所示

    【数据结构】链表OJ题(顺序表)(C语言实现)

    【数据结构】链表OJ题(顺序表)(C语言实现)

    在这里m1是已经为0了,所以会跳出循环,然后直接把nums2中剩余的数补到nums1的前面就可以了。

    第二种:m1还有剩余,n1已经分配完了,如下图所示

    【数据结构】链表OJ题(顺序表)(C语言实现)

    【数据结构】链表OJ题(顺序表)(C语言实现)

    像这种情况就可以直接结束了。

    知道这两种情况后,应该就能明白我们后面为什么会加一个循环,就是为了防止第一种情况的出现。

    【数据结构】链表OJ题(顺序表)(C语言实现)

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]