1-100的连续整数,乱序,重复一个数,丢失一个数,原地找出这两个数

问题描述:

1.比如inp={3,1,2,5,3}丢失了4,有两个3,原地找出这两个数。

2.为了方便起见这个连续数组从1开始;

解决:

1.元素3放在数组inp[3-1]的位置,该位置原来存的是2,再把2存入inp[2-1]……

状态栏:     {0   -1     }     {0-1-1    }     {-1-1-1    }    {-1-1-1  -1}   {-1-1-1   -1}

{3,1,2,5,3}     {3,1,2,5,3}     {3,1,2,5,3}     {3,1,2,5,3}     {3,1,2,5,3}

结果栏:     {      3     }     {   2 3     }     { 1 2 3     }     { 1 2 3   5}     { 1 2 3   5}

以上过程某个位置元素有两种状态,分别标识为0和1:比如第一个元素3,跳转到inp[3-1]后,它原来的位置inp[1-1]被访问过,却没有被跳转过(跳转到该位置),标识状态为0,inp[3-1]被跳转过,标识状态为-1;

1.input:int inp[]={3,1,2,5,3};

2.output:重复元素int  cf,丢失元素int  loss;

3.有个问题,比如{3,6,5,4,1},3跳到5跳到1,最后又跳回3。这是一个虚幻过程,中间6和4没有访问过。如何保证每个元素都被遍历?我们用两层循环嵌套;

4.下一跳元素可能有三种状态:
           0:被访问过,却没有被跳转过
          -1:被跳转过
    >0的数:既没被访问过,又没有被跳转过

如果下一跳是0,表示以前该元素跳出去过,但是没有跳到这里过,现在跳过来了,就改为-1;

如果下一跳是-1,表示该元素以前被访问过,又访问一次,可见是重复元素;

如果下一跳非0非-1,表示是新元素,跳到该元素,执行下一次循环;

思路大致如上,但是代码写起来费了老大力气了,看来还是底子薄,想提速还要多写啊!!

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int cf=-1,loss=-1;  //cf:重复的元素  loss:丢失的元素
int input[] = {2,3,6,4,2,1,7};

void fun(int inp[], int size)
{
  assert(inp!=NULL && size>1);
  int pre=inp[0],aft=inp[pre-1],i=0,j=pre-1;  //pre:当前元素值   aft:下一跳元素的值
  inp[0]=0;
  while(j<size){        //外层循环保证每个元素都被遍历到
   i=j;
   printf("outside loop : j = %d\n",j);
   while(inp[i]!=-1)    //内层循环是根据元素和数组下标的关系进行跳转循环
   {
     printf("inp[%d] = %d\n",i,inp[i]);
     if(inp[i]==0){     //0表示该位置i跳转到其他位置过,但其他位置从未跳转到此位置;-1表示其他元素跳转到该位置i过
         printf("inp[%d] == 0 is changed -1\n",i);
         inp[i]=-1;break;
     }
     else{
         pre=inp[i];    aft=inp[pre-1];
         printf("pre=%d ; aft = %d\n",pre,aft);
         if(aft==-1){    //下一跳为-1表示下一跳元素被访问过,表明inp[i]是重复元素
           cf=inp[i];
           inp[i]=0;     //该位置状态改变
           printf("doubled element = , %d\n",cf);
           break;
         }
         else{           //下一跳不为0,-1表示下一跳元素未被访问,循环到下一跳;
           inp[i]=-1;
           i=pre-1;
         }
     }
   }
   j++;
  }
  i=0;
  while(inp[i]==-1) i++;
  loss = i+1;
  printf("loss element is =  %d\n",loss);
}

int main(){
  fun(input,7);
  return 0;
}

看看结果:

[[email protected] Desktop]# ./a.out
outside loop : j = 1
inp[1] = 3
pre=3 ; aft = 6
inp[2] = 6
pre=6 ; aft = 1
inp[5] = 1
pre=1 ; aft = 0
inp[0] = 0
inp[0] == 0 is changed -1
outside loop : j = 2
outside loop : j = 3
inp[3] = 4
pre=4 ; aft = 4
outside loop : j = 4
inp[4] = 2
pre=2 ; aft = -1
doubled element = , 2
outside loop : j = 5
outside loop : j = 6
inp[6] = 7
pre=7 ; aft = 7
loss element is =  5
[[email protected] Desktop]
输入是:input[] = {2,3,6,4,2,1,7};
doubled element =  2
loss element is =  5

恩  目前为止没问题!
 

1-100的连续整数,乱序,重复一个数,丢失一个数,原地找出这两个数

时间: 2024-10-03 13:27:52

1-100的连续整数,乱序,重复一个数,丢失一个数,原地找出这两个数的相关文章

1-100的连续整数,乱序,丢失两个数,原地找出这两个数

问题描述: 1.比如inp={2,3,6,4,7}丢失了1,5,原地找出这两个数. 2.为了方便讨论这个连续数组从1开始到7截至,数组扩展到7位inp={2,3,6,4,7,0,0}: 解决: 1.利用数组元素值与数组下标关系,遍历整个数组,没有被遍历到的位置则为丢失元素所在位置,具体流程如下: 1.从头开始读数组inp[0]=2,根据值2跳转到数组下标为inp[2-1]的位置,得到inp[2-1]=3: 2.修改状态:这个过程中inp[0]位置跳出过,但未跳入过,用0表示这种状态.修改inp[

10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。

题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存). 关于中位数:数据排序后,位置在最中间的数值.即将数据分成两部分,一部分大于该数值,一部分小于该数值.中位数的位置:当样本数为奇数时,中位数=(N+1)/2 ; 当样本数为偶数时,中位数为N/2与1+N/2的均值(那么10G个数的中位数,就第5G大的数与第5G+1大的数的均值了). 分析:明显是一道工

在一个文件中有10G个整数,乱序排列,要求找出中位数

 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存). 关于中位数:数据排序后,位置在最中间的数值.即将数据分成两部分,一部分大于该数值,一部分小于该数值.中位数的位置:当样本数为奇数时,中位数=(N+1)/2 ; 当样本数为偶数时,中位数为N/2与1+N/2的均值(那么10G个数的中位数,就第5G大的数与第5G+1大的数的均值了). 分析:明显是一道

一起来刷《剑指Offer》——不修改数组找出重复的数字(思路及Python实现)

数组中重复的数字 在上一篇博客中<剑指Offer>-- 题目一:找出数组中重复的数字(Python多种方法实现)中,其实能发现这类题目的关键就是一边遍历数组一边查满足条件的元素. 然后我们在博客用最复杂的方式学会数组(Python实现动态数组)这篇博客中介绍了数组这一结构的本质,并自己动手实现了一个动态数组. 今天我们介绍一下另一道来自<剑指Offer>的关于数组的面试题--不修改数组找出重复的数字. 不修改数组找出重复的数字 题目二:不修改数组找出重复的数字 给定一个长度为 n+

Wireshark抓包实例分析TCP重复ACK与乱序

转载请在文首保留原文出处: EMC 中文支持论坛https://community.emc.com/go/chinese 介绍 TCP 的一大常见问题在于重复 ACK 与快速重传.这一现象的发生也是由于性能问题,本章讨论如何发现这一问题以及他们意味着什么. 另一个常见问题是前一片段丢失以及乱序片段.某些情况下,这一现象喻示着故障发生,可能是由于网络问题或是抓包中断. 更多信息 重复 ACK 与快速重传 : 当网速变慢时,重复 ACK 是可能的原因之一.大多数情况下,重复 ACK 的发生是由于高延

笔试算法题(28):删除乱序链表中的重复项 &amp; 找出已经排好序的两个数组中的相同项

出题:给定一个乱序链表,节点值为ASCII字符,但是其中有重复项,要求去除重复项并保证不改变剩余项的原有顺序: 分析:创建一个256(2^8)大小的bool数组,初始化为false,顺序读取链表,将字母对应位置为false的重新标记为true并保留节点,将字母对 应位置为true的保持并删除节点:时间复杂度为O(N),空间复杂度为常量.注意删除节点和不删除节点的情况下,pre和cur的移动操作不相同: 解题: 1 struct Node { 2 char value; 3 Node* next;

Shell脚本实现乱序排列文件内容的多种方法(洗牌问题)

洗牌问题:洗一副扑克,有什么好办法?既能洗得均匀,又能洗得快?即相对于一个文件来说怎样高效率的实现乱序排列? ChinaUnix 确实是 Shell 高手云集的地方,只要你想得到的问题,到那里基本上都能找到答案.r2007给出了一个取巧的方法,利用 Shell 的 $RANDOM 变量给原文件的每一行加上随机的行号然后根据这个随机行号进行排序,再把临时加上去的行号给过滤掉,这样操作之后得到的新文件就相当于被随机“洗”了一次: while read i;do echo "$i $RANDOM&qu

android图片显示(一) ———— 关于并发,乱序问题的处理

GridView加适配器的方式 如果仅仅只用gridview加适配器的方法,因为加载图片是需要时间的,如果你直接在getview中加载图片的话,就会影响UI,照成滑动的时候卡顿.所以,每加载一个图片的时候,我们会开启一个额外的进程,这样就不会影响UI主线程了. 仅仅只是开启一个额外的线程会出现"乱序"的问题.也就是"并发性"的问题. 因为,当你进行滑动的时候,凡是经过的区域都会打开线程加载图片,每个线程执行完毕的时间不是固定的.只有当线程执行完毕后,才会显示在当前屏

Android ListView异步加载图片乱序问题,原因分析及解决方案

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android所有系统自带的控件当中,ListView这个控件算是用法比较复杂的了,关键是用法复杂也就算了,它还经常会出现一些稀奇古怪的问题,让人非常头疼.比如说在ListView中加载图片,如果是同步加载图片倒还好,但是一旦使用异步加载图片那么问题就来了,这个问题我相信很多Android开发者都曾经遇到过,就是异步加载图片会出现错位乱序的情况.遇到这个问题时,不