关于去重题目的小总结

       ## 去重题目以及去重排序题目总结

最近离谱张同学,做了些去重类的题目,有一些新的感悟以及思考心得,这里全部分享给大家,
(由于其他博主也发表过相关博客,这里张同学借鉴了些,如果冒犯,立即删除)

我们可以先看这样一道题:如图所示(本题均选自鹏哥刷题课的题目)
在这里插入图片描述
如果要大家做的话,会怎么做呢?大家思考一下(10min)

     其实这种题目大致有这么几种思路:
    第一种:标记法:就是把要去重的元素,标记为-1或者你喜欢的符号,然后最后循环打印的时候,就打印不是标记的元素就好啦                         
    第二种:覆盖法(输入的数字如果和前面的重复了,那就删除,重新输入,这个操作我们看不到,但是实际上有。

方法1:标记法

思路:输入输出都很好表示,关键就是for循环中的if判断该咋弄?我们可以这样想:
既然是要比较元素,那我用两层for循环来用,比如我要比较1 1 2 2 3 3,那我的第一次for循环来遍历下标为0到4的元素,那就是1 1 2 2 3第一个元素与第二个1 2 2 3进行比较,第二个1与2 2 3 来进行比较,这样等到了最后的2的时候,我们与最后一个3进行比较就好了,如果叙述不清楚的话,下面如图所示。

for(i=1;i<n-1;i++)//这里的i=0,i<n-1就是上面的例子,1 1 2 2 
{
    for(j=i+1;j<n;j++)//而j=1+i,j<n就是第一次是五个元素,1 2 2 4 5,第二次是4个元素
    {
        if(a[j]==a[i])
        {
            a[j]=-1;//把要重复的元素来标记为-1就好
          }
     }
}

这样整体思路是不是就有了呢?
然后我们转化为代码的形式就好了啦

#include<stdio.h>
int main()
{
   
    int n=0,i=0,j=0,arr[100005];
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
   
        scanf("%d",&arr[i]);
     }
     
//去重的关键点:标记法

          
     for(i=0;i<n-1;i++)//这里的i=0,i<n-1就是上面的例子,1 1 2 2 4
   {
   
      for(j=i+1;j<n;j++)
//而j=i+1,j<n就是后五个元素,1 2 2 4 5
//===============================================
//j=i+1;就是从1开始,向后的去比较元素,这个点一定要注意
//================================================
     {
   
        if(arr[j]==arr[i])
        {
   
            arr[j]=-1;//把要重复的元素来标记为-1就好
          }
     }
  }

//去重完成之后打印出来    
     for(i=0;i<n;i++)
     {
   
         if(arr[i]!=-1)//切记一定要是==不是一个=,我已经在这里出过很多次错误了
         printf("%d ",arr[i]);
         
      } 
         
   return 0;
 }

方法2:覆盖法(输入的数字如果和前面的重复了,那就删除,重新输入,这个操作我们看不到,但是实际上有。

    其实可以这样来进行理解:n=5,输入1 2 3 3 2
   咱们第一个位置输一,第二个位置输二,第三个位置输三,当i等于四的时候,你应该输第四个元素,我输了一个三跟前面的三相同,所以i--,变成三了,然后你执行下一次循环的时候,循环要执行表达式三,i++变成了4,那么你要重新输入第四个位置的元素,你又输了一个二,然后输入二跟前面又相同了,所以i--又变成了三,这样的话。你看你输的数据是12332,这五个数据都输入了,但是因为后面的三和二跟前面的相同,所以在输第四个位置的时候,你输了一个三,变量i退回去了,变成3,然后你又输了一个二的时候,它又退回去了,所以你最终的数据还是一二三.那n减减就是一开始是5,然后发现两个重复的,第一次发现重复的n--变成4,第二次发现2也是重复的,然后n--变成了3,所以在最后打印的时候,就变成了1到3循环.
#include<stdio.h>
int main()
{
   
    int a[2001];
    int n,i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
   
        scanf("%d",&a[i]);
        for(j=1;j<i;j++)
        {
   
            if(a[j]==a[i])
            {
   
                i=i-1;
                n=n-1;
            }
        } 
}
    for(i=1;i<=n;i++)
    {
   
        printf("%d ",a[i]);
    }
    return 0;
    
}

 方法三:覆盖法的盗版(1),但是这种覆盖法只能弄连续的数字,无法在乱序中找到并且去重,(牛客上过不了)但是这个思路很好
 针对于这个点我们可以这样想:先上代码啦
 for
  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值