【数据结构刷题】数组oj

简介: 【数据结构刷题】数组oj
前言:
  本文章是关于在力扣上面的数组相关面试题的讲解,包括:
  1.原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1),
  2.删除排序数组中的重复项。
  3. 合并两个有序数组。


一.原地移除数组中所有的元素val


题目:

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


1.1时间复杂度为O(N^2),空间复杂度为O(1)

写一段原地移除数组中所有的元素val,要求时间复杂度为O(N^2),空间复杂度为O(1)的代码实现:

思路:遇到这个val后面的元素往前面覆盖。

d03b062125a44ad7836e015052407432.png

  int removeElement(int* nums, int numsSize, int val) {
    int i, j;
    int newSize = numsSize;
    for (i = 0; i < newSize; i++) {
        if (nums[i] == val) {
            for (j = i; j < newSize - 1; j++) {
                nums[j] = nums[j + 1];
            }
            newSize--;
            i--; // 重复检查当前位置
        }
    }
    return newSize; } 

int main() {

int nums[] = { 0, 1, 2, 2, 3, 0, 4, 2 };

int numsSize = sizeof(nums) / sizeof(nums[0]);

int val = 2;

int newSize = removeElement(nums, numsSize, val);
printf("修改后的数组: ");
for (int i = 0; i < newSize; i++) {
    printf("%d ", nums[i]);
}
return 0; } 


1.2时间复杂度为O(N),空间复杂度为O(N)

写一段原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(N)的代码实现:

思路:

b0865ae0a40147caac964f7fe3314689.png

#include <stdlib.h> int* removeElements(int* nums, int numsSize, int val, int* newSize) {
     int i, j;
         int* tmp = (int*)malloc(numsSize * sizeof(int)); // 创建一个临时数组
     int count = 0; // 计数器,记录移除元素后的数组长度
      for (i = 0; i < numsSize; i++) {
         if (nums[i] != val) {
             tmp[count] = nums[i]; // 将非 val 元素保存到临时数组
             count++;
         }
     }
    *newSize = count; // 更新新数组的长度
    return tmp; // 返回临时数组的指针
     }
int main() {
    int nums[] = { 0, 1, 2, 2, 3, 0, 4, 2 };
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    int val = 2;
    int newSize;
    int* newArray = removeElements(nums, numsSize, val, &newSize);
    printf("移除元素后的数组: ");
    for (int i = 0; i < newSize; i++) {
        printf("%d ", newArray[i]);
    }
    printf("\n新长度: %d\n", newSize);
    free(newArray); // 释放临时数组的内存
    return 0; } ```


1.3符合此题的正确写法:

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

写法2与这篇文章的唯一的区别是本文章需要return j,其余部分一样,而写法1的大致思路画图思路相差不大,就不用动图演示了,传送门–>序列中删除指定数字,有动图演示

图解:

c1ae5c439702414b90ff2bb2842b5b02.png

#include<stdio.h>
/写法一
int removeElement(int *nums,int numsSize,int val)
{
  int src = 0;
  int dst = 0;
  while (src < numsSize)
  {
    if (nums[src] != val)
    {
      nums[dst++] = nums[src++];
    }
    else
    {
      src++;
    }
  }
  return dst;
}
//写法二
int removeElement(int* nums, int numsSize, int val){
      int i=0;
      int j=0;
      for(i=0;i<numsSize;i++)
      {
       if(nums[i]!=val)
      {
        nums[j++]=nums[i];
      }
      }
        return j;
}


int main() {

int nums[] = { 0, 1, 2, 2, 3, 0, 4, 2 };

int sz =sizeof(nums) / sizeof(nums[0]);

int val = 2;

int ret=removeElement(nums, sz, val);

printf(“%d”,ret);

}


二. 删除排序数组中的重复项。


题目:

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

动图演示:

89be2a4e1fb54cefa73999a8c86798bb.gif

#include<stdio.h>
int removeDuplicates(int* nums, int numsSize) {
  int src = 1, dst = 0;
  while (src < numsSize)
  {
    if (nums[src] != nums[dst])
    {
      nums[++dst] = nums[src++];
    }
    else
    {
      src++;
    }
  }
  return dst+1;//因为dst是下标,所以要+1
}
int main()
{
  int nums[] = { 0,0,1,1,1,2,2,3,3,4 };
  int sz = sizeof(nums) / sizeof(nums[0]);
  int ret=removeDuplicates(nums, sz);
  printf("%d", ret);
}


执行:

2640158c4a1f420aa657bbf0fa6b0fe3.png


三. 合并两个有序数组


题目:

https://leetcode.cn/problems/merge-sorted-array/

思路:无论是下面哪种情况,nums1数组都是目标数组,都是长的那个。

要是end2先结束,那就不用拷贝到目标数组nums1,直接打印nums1即可

若是end1先结束,需要先把nums2(短数组的元素)拷贝到nums1,再打印


3.1end1>0,end2<0

769641a110914700a4743ab402e1dc19.gif


3.2end1<0,end2>0

61276e9e714c439793c356d2a7f36d57.gif


代码实现:

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


执行:

6c9398a3103f4c6092343519333eb4c4.png

文章到这就写完了,如有错误欢迎指正,谢谢!

相关文章
|
1月前
|
存储 Java 程序员
数据结构之 - 深入了解数组数据结构
数据结构之 - 深入了解数组数据结构
38 6
|
1月前
|
存储 算法 搜索推荐
探索常见数据结构:数组、链表、栈、队列、树和图
探索常见数据结构:数组、链表、栈、队列、树和图
99 64
|
1月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
30 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
1月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
26 7
|
1月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
20 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
2月前
|
存储 Java
java数据结构,线性表顺序存储(数组)的实现
文章介绍了Java中线性表顺序存储(数组)的实现。线性表是数据结构的一种,它使用数组来实现。文章详细描述了线性表的基本操作,如增加、查找、删除、修改元素,以及其他操作如遍历、清空、求长度等。同时,提供了完整的Java代码实现,包括MyList接口和MyLinearList实现类。通过main函数的测试代码,展示了如何使用这些方法操作线性表。
|
3月前
|
存储 Java 程序员
"揭秘HashMap底层实现:从数组到链表,再到红黑树,掌握高效数据结构的秘密武器!"
【8月更文挑战第21天】HashMap是Java中重要的数据结构,采用数组+链表/红黑树实现,确保高效查询与更新。构造方法初始化数组,默认容量16,负载因子0.75触发扩容。`put`操作通过计算`hashCode`定位元素,利用链表或红黑树处理冲突。`get`和`remove`操作类似地定位并返回或移除元素。JDK 1.8优化了链表转红黑树机制,提升性能。理解这些原理能帮助我们更高效地应用HashMap。
45 0
|
15天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
90 9
|
5天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
15 1
|
8天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。

热门文章

最新文章