牛客网刷题 | BC124 序列中删除指定数字

目前主要分为三个专栏,后续还会添加:

        专栏如下:                 C语言刷题解析       C语言系列文章       我的成长经历

感谢阅读!

初来乍到,如有错误请指出,感谢!


描述

有一个整数序列(可能有重复的整数),现删除指定的某一个整数,输出删除指定数字之后的序列,序列中未被删除数字的前后位置没有发生改变。

数据范围:序列长度和序列中的值都满足 1≤n≤501≤n≤50

输入描述:

第一行输入一个整数(0≤N≤50)。

第二行输入N个整数,输入用空格分隔的N个整数。

第三行输入想要进行删除的一个整数。

输出描述:

输出为一行,删除指定数字之后的序列。


思路 

  1. 初始化变量和数组

    • 声明两个整数变量 a 和 b,分别用于存储序列的长度和要删除的数字。
    • 声明一个大小为50的整数数组 arr,并将其初始化为全零。这个数组用于存储输入的整数序列。
  2. 读取输入数据

    • 使用 scanf("%d", &a); 读取用户输入的第一个整数,该整数表示序列的长度 a
    • 使用一个 for 循环,通过 scanf("%d", &arr[i]); 逐个读取序列中的整数,并存储在数组 arr 中。
  3. 读取要删除的整数

    • 使用 scanf("%d", &b); 读取用户输入的第三个整数,该整数是要从序列中删除的数字。
  4. 标记要删除的元素

    • 使用一个 for 循环遍历数组 arr
    • 在每次迭代中,检查当前元素 arr[i] 是否等于 b
    • 如果当前元素等于 b,则将 arr[i] 设置为 0,表示该元素需要被删除。
  5. 输出结果

    • 再次使用一个 for 循环遍历数组 arr
    • 在每次迭代中,检查当前元素 arr[i] 是否不等于 0
    • 如果不等于 0,则使用 printf("%d ", arr[i]); 输出该元素,并在后面加一个空格。
    • 循环结束后,使用 printf("\n"); 换行,确保输出格式正确。

代码

 

#include <stdio.h>

int main() {

    int a,b;
    int arr[50] = {0};
    scanf("%d",&a);
    for(int i = 0;i < a;i++)
    {
        scanf("%d",&arr[i]);
    }

    scanf("%d",&b);//要删的数字
    for(int i = 0;i < a;i++)//将要删的数字赋值为0
    {
        if(arr[i] == b)
            arr[i] = 0;
    }

    for(int i = 0;i < a;i++)
        if(arr[i] != 0)
        {
            printf("%d ",arr[i]);//打印非0的数字
        } 
        

    return 0;
}
#include <stdio.h>

int main() {
    int a, b; // 声明两个整数变量,a用于存储序列长度,b用于存储要删除的数字
    int arr[50] = {0}; // 声明一个大小为50的整数数组,并初始化为全零

    // 读取序列的长度
    scanf("%d", &a);

    // 读取序列中的每一个整数
    for (int i = 0; i < a; i++) {
        scanf("%d", &arr[i]); // 逐个读取序列中的整数并存储在数组arr中
    }

    // 读取要删除的整数
    scanf("%d", &b);

    // 将要删除的数字标记为0
    for (int i = 0; i < a; i++) {
        if (arr[i] == b) { // 检查当前元素是否等于要删除的数字
            arr[i] = 0; // 如果相等,则将该元素设置为0,表示需要删除
        }
    }

    // 输出非0的数字
    for (int i = 0; i < a; i++) {
        if (arr[i] != 0) { // 检查当前元素是否不等于0
            printf("%d ", arr[i]); // 如果不等于0,则输出该元素,并在后面加一个空格
        }
    }

    // 输出完成后换行
    printf("\n");

    return 0;
}



 代码执行流程

  1. 初始化变量和数组

    • 声明变量 a 和 b,并声明一个大小为50的整数数组 arr,初始化为全零。
  2. 读取序列长度

    • 使用 scanf("%d", &a); 读取用户输入的第一个整数,该整数表示序列的长度 a
  3. 读取序列中的整数

    • 使用一个 for 循环,通过 scanf("%d", &arr[i]); 逐个读取序列中的整数,并存储在数组 arr 中。
    • 例如,如果输入是 5,接着输入 1 2 3 4 3,那么数组 arr 将变为 [1, 2, 3, 4, 3, 0, 0, ..., 0](前5个元素为输入的数字,其余为默认的0)。
  4. 读取要删除的整数

    • 使用 scanf("%d", &b); 读取用户输入的第三个整数,该整数是要从序列中删除的数字。
    • 例如,如果输入是 3,那么 b 的值将是 3
  5. 标记要删除的元素

    • 使用一个 for 循环遍历数组 arr
    • 在每次迭代中,检查当前元素 arr[i] 是否等于 b
    • 如果当前元素等于 b,则将 arr[i] 设置为 0,表示该元素需要被删除。
    • 例如,对于数组 [1, 2, 3, 4, 3, 0, 0, ..., 0] 和 b = 3,循环结束后数组 arr 将变为 [1, 2, 0, 4, 0, 0, 0, ..., 0]
  6. 输出结果

    • 再次使用一个 for 循环遍历数组 arr
    • 在每次迭代中,检查当前元素 arr[i] 是否不等于 0
    • 如果不等于 0,则使用 printf("%d ", arr[i]); 输出该元素,并在后面加一个空格。
    • 循环结束后,使用 printf("\n"); 换行,确保输出格式正确。
    • 例如,对于数组 [1, 2, 0, 4, 0, 0, 0, ..., 0],程序将输出 1 2 4  并换行。

示例

假设输入如下:

5
1 2 3 4 3
3

程序的执行过程如下:

  1. 读取序列长度 a = 5
  2. 读取序列 [1, 2, 3, 4, 3]
  3. 读取要删除的整数 b = 3
  4. 遍历序列并将所有等于 3 的元素标记为 0,得到 [1, 2, 0, 4, 0]
  5. 再次遍历序列并输出所有非 0 的元素,即 1 2 4 并换行。

最终输出为:

1 2 4  


深入探究

删除指定整数后的序列

问题描述

给定一个整数序列和一个目标整数,我们需要删除序列中所有等于目标整数的元素,并输出剩余的序列。具体来说:

  • 输入:
    • 第一行输入一个整数 n(1 ≤ n ≤ 50),表示序列的长度。
    • 第二行输入 n 个整数,用空格分隔。
    • 第三行输入一个整数 b,表示要删除的数字。
  • 输出:
    • 删除指定整数后的序列,元素之间用空格分隔。

示例输入输出

  • 输入:
5
1 2 3 4 3
3
  • 输出:
1 2 4

 初步解决方案 我们可以通过两次遍历来解决这个问题:第一次遍历标记要删除的元素,第二次遍历输出非零元素。以下是初步代码实现:

#include <stdio.h>

int main() {
    int a, b;
    int arr[50] = {0};

    // 读取序列的长度
    scanf("%d", &a);

    // 读取序列中的每一个整数
    for (int i = 0; i < a; i++) {
        scanf("%d", &arr[i]);
    }

    // 读取要删除的整数
    scanf("%d", &b);

    // 将要删除的数字标记为0
    for (int i = 0; i < a; i++) {
        if (arr[i] == b) {
            arr[i] = 0;
        }
    }

    // 输出非0的数字
    for (int i = 0; i < a; i++) {
        if (arr[i] != 0) {
            printf("%d ", arr[i]);
        }
    }

    // 输出完成后换行
    printf("\n");

    return 0;
}

时间复杂度分析

  • 时间复杂度: O(n),其中 n 是序列的长度。程序需要两次遍历数组。
  • 空间复杂度: O(1),除了输入数组外,没有使用额外的空间。

优化方案 为了进一步提高效率,我们可以使用双指针法直接在原数组上进行删除操作,避免使用额外的空间。以下是优化后的代码实现:

优化思路

  • 双指针法: 使用两个指针,一个用于遍历数组,另一个用于记录有效元素的位置。这样可以在一次遍历中完成删除操作。

优化代码实现

#include <stdio.h>

int main() {
    int a, b;
    int arr[50];

    // 读取序列的长度
    scanf("%d", &a);

    // 读取序列中的每一个整数
    for (int i = 0; i < a; i++) {
        scanf("%d", &arr[i]);
    }

    // 读取要删除的整数
    scanf("%d", &b);

    int k = 0; // 用于记录有效元素的位置

    // 使用双指针法将有效元素移动到数组前面
    for (int i = 0; i < a; i++) {
        if (arr[i] != b) {
            arr[k++] = arr[i];
        }
    }

    // 输出有效元素
    for (int i = 0; i < k; i++) {
        printf("%d ", arr[i]);
    }

    // 输出完成后换行
    printf("\n");

    return 0;
}

优化后的时间复杂度分析

  • 时间复杂度: O(n),只需要一次遍历数组即可完成删除操作。
  • 空间复杂度: O(1),没有使用额外的空间。

进一步讨论 处理大数据集 当数据集非常大时,上述方法仍然保持线性时间复杂度,但可能需要考虑其他优化策略,如分块处理或使用更高效的数据结构。

多线程处理 对于非常大的数据集,可以考虑使用多线程来提高处理速度。不过,在这个问题规模下,多线程带来的收益可能有限。

内存管理 在某些情况下,可能需要考虑内存管理和垃圾回收机制。然而,由于我们的数组大小固定且较小,这一方面的影响不大。

参考文献

  1. 《算法导论》 by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
    • 这本书是一本经典的算法教材,涵盖了各种排序和搜索算法及其优化方法。
  2. GeeksforGeeks (GeeksforGeeks | A computer science portal for geeks)
    • GeeksforGeeks 提供了大量的编程问题和解决方案,非常适合学习和练习算法。
  3. LeetCode (https://leetcode.com/)
    • LeetCode 是一个在线平台,提供了大量的编程题目和面试准备资源,适合提高算法技能。
  4. Codeforces (https://codeforces.com/)
    • Codeforces 是一个流行的竞赛平台,提供了高质量的比赛和编程题目,有助于提高解决问题的能力。

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值