2015年东华大学研究生复试机试题:数组去重

本文介绍了如何在C语言中使用双指针方法高效地从递增有序数组中去除重复元素,保持时间复杂度为O(n)且空间复杂度为O(1),并提供了相应的代码实现和经验总结。
摘要由CSDN通过智能技术生成

Problem Description

  1. 在一个递增有序的数组中,有数值相同的元素存在,程序的功能是去掉数值相同的元素,使数组中不再有重复的元素。
  2. 例如:(7,10,10,21,30,42,42,42,51)将变成(7,10,21,30,42,51)。
  3. 主函数main中,首先输入有序数组的元素数目及各元素的值,然后将数组及元素数目传入函数fun中,函数fun完成删除重复元素的操作。
  4. 要求:尽量优化算法的时间复杂度与空间复杂度。

解题思路

  1. 用int类型数组nums保存有序元素。
  2. 用变量j表示去重后数组的指针,初值为0,变量i表示遍历数组nums的指针,初值为1。
  3. 通过对比i和j指向的数组元素,若相同,则指针i后移,若不同,则指针j后移,并将i位置的元素赋值给j位置。
  4. 遍历完整个nums数组,去重完成,j的值为后移次数,即不同元素对比次数,去重数组的元素数目为j + 1。
  5. 时间复杂度为O(n),n为数组元素数目;空间复杂度为O(1)。

经验总结

  1. 一开始使用的是count数组记录元素是否出现,若输入的元素过大,则空间复杂度随之上涨。
  2. 用双指针的思想,空间复杂度始终为O(1)。

代码实现(C)

#include <stdio.h>

#define MaxSize 1000

// 去重函数,输入数组及元素个数
void fun(int nums[], int *n) {
    // 若元素个数为1,则无需去重
    if (*n <= 1) return;
    // j是去重数组的指针,初值为0
    int j = 0;
    // i是原数组指针,初值为1,指向j后面的一个元素
    for (int i = 1; i < *n; ++i) {
        // i和j位置的元素不相同
        if (nums[j] != nums[i]) {
            j++;                    // j指针后移
            nums[j] = nums[i];      // i位置元素赋值到j位置
        }
    }
    // j表示不同元素的对比次数,去重数组元素数目为j + 1
    *n = j + 1;
}

int main() {
    int nums[MaxSize], n;
    while (~scanf("%d", &n)) {
        for (int i = 0; i < n; ++i)
            scanf("%d", &nums[i]);
        fun(nums, &n);
        for (int i = 0; i < n; ++i)
            printf("%d ", nums[i]);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值