面试题:一个判断连续数存在性的算法

从0~13中任取出7个数,然后判断这7个数中是否存在连续的5个数, 规则如下:
1) 7个数可以是重复的数.
2) 0可以表示任意数
例子如下:
0, 1, 4, 3, 8, 0, 13--->true: 1-2-3-4-5
0, 1, 1, 1, 9, 10, 0--->false
0, 1, 3, 9, 10, 11, 12->true: 9-10-11-12-13
0, 0, 0, 0, 0, 0, 0->true: 0-1-2-3-4

这是最近看到的一个算法题, 粗粗一看, 觉得很简单, 可是慢慢往里面想,觉得要考虑的还是挺多的。现在把它实现出来放在这里,当然,加了几个参数使其更加通用。 希望对大家有些参考价值。写的不明白的地方,有错误的地方大家可以指出来;大家如果有好的思路的话也希望能写下来共享一下。以下是代码与注释:

 

#include  < stdio.h >
#include 
< iostream >
using   namespace  std;

/*
从0~13中任取出7个数,然后判断这7个数中是否存在连续的5个数, 规则如下:
1) 7个数可以是重复的数.
2) 0可以表示任意数
例子如下:
0, 1, 4, 3, 8, 0, 13--->true: 1-2-3-4-5
0, 1, 1, 1, 9, 10, 0--->false
0, 1, 3, 9, 10, 11, 12->true: 9-10-11-12-13 
0, 0, 0, 0, 0, 0, 0->true: 0-1-2-3-4
*/


//  Helper functions
void  outputarray( int  a[],  int  n)
{
    
for ( int  i  =   0 ; i  <  n;  ++ i) cout << a[i] << "   " ;
    cout
<< endl;
}

void  outputresult( int  nstart,  int  m)
{
    cout
<< " Continuous Array: " ;
    
while (m -- )    cout << nstart ++<< "   " ;
    cout
<< endl;
}

//  Return if the n elements array contains m continuous numbers, the elements must large than 0
//  this is a common implementation
bool  Is_n_Contains_m_ContinuousNum( int  a[],  int  n,  int  m) 
{
    
//  step 1: get num of 0
     int  nZeroNum  =   0 ;
    
for ( int  i  =   0 ; i  <  n;  ++ i)
        
if ( 0   ==  a[i])  ++ nZeroNum;

    cout
<< " Original Array:   " ; outputarray(a, n);

    
//  step 2: if we have enough 0, get continuous num is easy.
     if (nZeroNum  >=  m - 1 )
    {
        
int  min  =  a[ 0 ];
        
for ( int  i  =   1 ; i  <  n;  ++ i)
            
if (a[i]  <  min  ||   0   ==  min) min  =  a[i];
        outputresult(min, m);
        
return   true ;
    }
    
//  not enough zero, we need to refine the judgement
     else
    {
        
//  step 2.1: sort the array. (bubble sort, ascending)
         bool  bIsDone  =   false ;
        
for ( int  i  =  n - 1 ; i  >=   0   &&   ! bIsDone;  -- i)
        {
            bIsDone 
=   true ;
            
for ( int  j  =   0 ; j  <  i;  ++ j)
            {
                
if (a[j + 1 <  a[j])
                {
                    bIsDone 
=   false ;
                    
int  tmp  =  a[j + 1 ];
                    a[j
+ 1 =  a[j];
                    a[j] 
=  tmp;
                }
            }
        }

        cout
<< " Sorted Array:     " ; outputarray(a, n);

        
//  step 2.2: remove redundant num except 0
         int  aa[ 256 ];
        aa[
0 =  a[ 0 ];
        
int  j  =   1 ;
        
for ( int  i  =   0 ; i  <  n - 1 ++ i)
        {
            
if (a[i + 1 !=  a[i]  ||   0   ==  a[i + 1 ])
                aa[j
++ =  a[i + 1 ];
        }
        memcpy(a, aa, j 
*   sizeof (aa[ 0 ]));
        n 
=  j;
        
if (n  <  m)  return   false ;

        cout
<< " Unique Array:     " ; outputarray(a, n);


        
//  step 2.3: get index of first non-zero element
         int  nIndex  =   0 ;
        
for ( int  i  =   0 ; i  <  n;  ++ i)
        {
            
if (a[i]  !=   0
            {
                nIndex 
=  i;
                
break ;
            }
        }

        
//  step 2.4: refined judgement
        
//  if n = 7; m = 5; nZeroNum = 2;
        
//  if we can get continious number without zero or only with 1 zero, then with 2 zero is ok too.
        
//  so if we got x zeros, we need to check if can success with (0 ~ x-1) zeros
         for ( int  k  =   0 ; k  <=  nZeroNum;  ++ k)
        {
            
int  nInterval  =  m  -  k  -   1 ;
            
for ( int  i  =  nIndex; i  <  n - nInterval;  ++ i)
            {
                
//  when k = nZeroNum = 2;
                
//  if the a[i+nInterval] - a[i] ranged in (nInterval, m-1), then it is continuous)
                
//  means a[i+2] - a[i] ranged in (2, 4), for example:
                
//  1 3 5;  1 2 3; 1 2 4;
                 if (a[i + nInterval]  -  a[i]  <=  m - 1   &&  a[i + nInterval]  -  a[i]  >=  nInterval)
                {
                    outputresult(a[i], m);
                    
return   true ;
                }
            }
        }
    }

    
return   false ;
}


int  main( int  argc,  char   * argv[])
{
    
int  a[]  =  { 0 0 0 0 0 0 0 };
    
if ( ! Is_n_Contains_m_ContinuousNum(a,  sizeof (a) / sizeof (a[ 0 ]), 5 ))
        cout
<< " Continuous Array:Not Found " ;
    
return   0 ;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值