zoukankan      html  css  js  c++  java
  • 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
    ",j);
       while(inp[i]!=-1)    //内层循环是根据元素和数组下标的关系进行跳转循环
       {
         printf("inp[%d] = %d
    ",i,inp[i]);
         if(inp[i]==0){     //0表示该位置i跳转到其他位置过,但其他位置从未跳转到此位置;-1表示其他元素跳转到该位置i过
             printf("inp[%d] == 0 is changed -1
    ",i);
             inp[i]=-1;break;
         }
         else{
             pre=inp[i];    aft=inp[pre-1];
             printf("pre=%d ; aft = %d
    ",pre,aft);
             if(aft==-1){    //下一跳为-1表示下一跳元素被访问过,表明inp[i]是重复元素
               cf=inp[i];
               inp[i]=0;     //该位置状态改变
               printf("doubled element = , %d
    ",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
    ",loss);
    }
    
    int main(){
      fun(input,7);
      return 0;
    }

    看看结果:

    [root@admin 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
    [root@admin Desktop]
    输入是:input[] = {2,3,6,4,2,1,7};
    doubled element =  2
    loss element is =  5

    恩 目前为止没问题!
     
  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/McQueen1987/p/3912742.html
Copyright © 2011-2022 走看看