服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言经典顺序表真题演练讲解

C语言经典顺序表真题演练讲解

2022-11-07 13:32三分苦 C/C++

程序中经常需要将一组数据元素作为整体管理和使用,需要创建这种元素组,用变量记录它们,传进传出函数等。一组数据中包含的元素个数可能发生变化,顺序表则是将元素顺序地存放在一块连续的存储区里,元素间的顺序关系

1、移除元素

链接直达:

https://leetcode-cn.com/problems/remove-element/

题目:

C语言经典顺序表真题演练讲解

思路:

法一:依次挪动数据进行覆盖

从第一个数据开始进行依次遍历,如同示例1,依次遍历数组,找到移除的元素2就把后面的数据往前挪动进行覆盖,如图所示:

C语言经典顺序表真题演练讲解

此法有个缺陷,题目中明确指出使用空间复杂度O(1)的方法解决此问题,而此法的空间复杂度刚好为O(1),可以解决,不过考虑周全些,时间复杂度在情况最坏时为O(N^2),出现全是val的情况,将会挪动n-1+n-2+……出现了等差数列,时间复杂度为O(N^2),此法不是最优,换。

法二:双指针1.0

依次遍历原数组,看是不是val,把不是val的值,拷贝到新数组,此法的时间复杂度是O(N),空间复杂度也是O(N),可是题目明确指出空间复杂度要为O(1),所以此法不行,但是仔细想想,如果继续用此法双指针,但是不另开数组,就在原数组上改动可否呢?,由此引出双指针2.0

法三:双指针2.0

此法是在法二的基础上进行的升级,法二需要开辟额外数组,此法直接原数组改动。首先定义两个变量src和dst为0,都作为数组nums的下标,依次遍历src看nums[src]是否为val,若不是,将其赋给下标dst,再src++,dst++。若nums[src]=nums[dst],则只把src++,dst不动,最后再把长度dst返回即可。

代码如下:

int removeElement(int* nums, int numsSize, int val){
  int dst=0;
  int str=0;
  while(str<numsSize)
  {
      if(nums[str]==val)
      {
          str++;
      }
      else
      {
          nums[dst]=nums[str];
          dst++;
          str++;
      }
  }
  return dst;
}

 

2、删除有序数组中的重复项

链接直达:

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

题目:

C语言经典顺序表真题演练讲解

思路:

双指针(不额外开数组)

此题和上题类似,同样可以采用双指针,并在原数组进行改动,只需要定义两个变量dst和src作为数组nums的下标,但此时做出小变动,把src从下标1开始,而dst从下标0开始。让nums[src]每次和它前一个也就是nums[src-1]相比较,如果相等,则src++,若不等就把nums[src-1]赋给nums[dst],再dst++,src++。

注意:

执行完上述操作后,还存在一个问题,那就是没把src的最后一个下标的值放到nums[dst]里头去,就如同本题的示例,当src走到倒数第二个值3的时候,和前一个3相等,此时需要++src,现在nums[src]就是4,和前一个值不相等,把3赋给nums[dst],此时src再++到空了,没有数据和4比较了,越界,所以4就漏掉了。在如同当后面2个数字同为3的时候,因为一直相等,src同样+到空,3同样漏掉,所以无论哪种情况,都要把最后一个数字移到nums[dst]上

画图演示:

C语言经典顺序表真题演练讲解

代码如下:

int removeDuplicates(int* nums, int numsSize){
  int dst=0;
  int src=1;
  while(src<numsSize)
  {
      if(nums[src]==nums[src-1])
      {
          src++;
      }
      else
      {
          nums[dst]=nums[src-1];
          dst++;
          src++;
      }
  }
  nums[dst]=nums[numsSize-1];
  dst++;
  return dst;
}

 

3、合并两个有序数组

链接直达:

合并两个有序数组

题目:

C语言经典顺序表真题演练讲解

思路:

法一:memmove + sort排序(冒泡、qsort等)

此法确实可以,不过当题目中明确指出要用时间复杂度O(N)的方法解决此问题的话,那么此法就行不通了,因为冒泡的时间复杂度为O(N^2),而qsort的时间复杂度为O(N*logN)。均不是O(N),所以得换。

法二:归并1.0

依次比较,每次把小的放到归并数组。此法需要开辟第三方数组a。其次,需要定义 i ,j ,dst 三个变量分别用来表示数组nums1,nums2,a的第一个下标,如果nums1[ i ]<nums[ j ],则a[dst++]=nums1[ i++ ],反之a[dst++]=nums2[ i++ ],依次遍历下去,当其中一个走完了,就把剩下的全部放到a数组里头去,此法的最大问题就是需要额外开辟一个数组,以空间换时间,导致空间复杂度为O(N),但是我们在基于此法的基础上可以进行升级,如下:

法三:归并2.0

此法是在法二的基础上进行升级,直接在nums1原数组上进行改动,思想和法二差不多。不过有个需要改变的地方,法二是正着遍历数组,但是此法则需要倒着来遍历数组。那么此时的 i 变量就是nums1数组第m-1个下标,j变量就是nums2数组第n-1个下标,dst变量就是nums1数组最后一个元素下标(m+n-1)。实现原理同法二,不做过多赘述。注意:如果nums2数组的下标 j 先结束,那么nums1剩下的数组刚好排在前面,不需要动,如果是nums1数组的下标 i 先结束,则需要把nums2数组剩余的值赋到nums1数组上去。

画图演示:

C语言经典顺序表真题演练讲解

代码如下:

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

到此这篇关于C语言经典顺序表真题演练讲解的文章就介绍到这了,更多相关C语言 顺序表内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/bit_zyx/article/details/123578575

延伸 · 阅读

精彩推荐
  • C/C++LintCode-排序列表转换为二分查找树分析及实例

    LintCode-排序列表转换为二分查找树分析及实例

    这篇文章主要介绍了LintCode-排序列表转换为二分查找树分析及实例的相关资料,需要的朋友可以参考下...

    wangyuquanliuli9722021-05-08
  • C/C++C++11 thread多线程编程创建方式

    C++11 thread多线程编程创建方式

    这篇文章主要介绍了C++11 thread多线程编程的相关知识,包括线程的创建方式结束方式及互斥锁的实例代码详解,本文给大家介绍的非常详细,对大家的学习...

    ~怎么回事啊~10392022-03-09
  • C/C++C++实现停车场管理系统

    C++实现停车场管理系统

    这篇文章主要为大家详细介绍了C++实现停车场管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Akatsuki__Itachi7592021-06-15
  • C/C++OpenGL绘制贝塞尔曲线

    OpenGL绘制贝塞尔曲线

    这篇文章主要为大家详细介绍了OpenGL绘制贝塞尔曲线,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    薛昭君5042021-09-01
  • C/C++C语言利用数组和文件实现登录注册功能

    C语言利用数组和文件实现登录注册功能

    这篇文章主要为大家详细介绍了C语言利用数组和文件实现登录注册功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考...

    Vecace7732021-10-16
  • C/C++C语言实现关机小程序

    C语言实现关机小程序

    这篇文章主要为大家详细介绍了C语言实现关机小程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    _Black_Sky5602021-08-19
  • C/C++使用VC++实现打印乘法口诀表

    使用VC++实现打印乘法口诀表

    本文给大家分享的是一个超级简单的小例子,使用vc++打印乘法口诀表,给需要的小伙伴参考下吧。...

    C++教程网6412021-02-22
  • C/C++C语言中的malloc使用详解

    C语言中的malloc使用详解

    这篇文章主要介绍了C语言中的malloc的使用,包括用其动态申请二维数组等功能,需要的朋友可以参考下...

    zinss269144542021-03-06