检查数组中是否有任何重复的元素递归

时间:2010-06-01 01:31:09

标签: c# java recursion

如果整数数组v中有任何重复的元素,我必须递归地找到。 该方法必须具有以下签名:

boolean hasRepeatedElements(int[] v) 

我无法看到以任何方式递归执行此操作而无需为此方法定义另一个方法或至少另一个重载(例如,该方法需要使用该元素)。首先,我考虑检查当前v是否有一些元素等于第一个元素,然后创建一个带有L-1元素等的新数组,但这似乎效率很低。这是唯一的方法吗?

我在这里错过了什么吗?

6 个答案:

答案 0 :(得分:5)

我同意递归在这里并不十分必要,但可以使用它。 你知道快速排序算法吗?在这里可以采取相同的分而治之的方法。

boolean hasRepeatedElements(list v) 
    if v.length <= 1 return false;
    List less, greater;
    x = v[0];
    for each y in v, except v[0]
        if y == x
            return true;
        else if y < x
            less.add(y);
        else if y > x
            greater.add(y);
    end;
    return hasRepeatedElements(less) || hasRepeatedElements(greater);
end;

您还可以添加随机化以使算法统计为O(n * log(n))。

http://en.wikipedia.org/wiki/Quicksort

答案 1 :(得分:4)

我确信那些比我聪明的人可以更有效地做到这一点,但至少它有效。

bool hasRepeatedElements(int[] v)
        {
            if (v.Length > 1)
            {
                int[] subArray = new int[v.Length - 1];
                for (int i = 1; i < v.Length; i++)
                {
                    if (v[0] == v[i])
                        return true;
                    else
                        subArray[i - 1] = v[i];
                }
                return hasRepeatedElements(subArray);
            }

            return false;
        }

答案 2 :(得分:1)

迭代会更快。或者使用容器类。你的方式会奏效,但效率不高。如果这是C,而不是复制你可以只调用hadRepeatedElements(v + 1)

答案 3 :(得分:1)

您可以同时进行排序和比较,因为这实际上是排序算法的作用。如果您的排序算法是递归的,那么您赢了:)

boolean hasRepeatedElements(int[] v) {
  if (v.length <= 1) return false;
  boolean switched = false;
  int[] sub = new int[v.length];
  for (int i = 0; i < v.length; i++)
    sub[i] = v[i];
  for (int i = 0; i < sub.length - 1; i++) {
    if (sub[i] > sub[i + 1]) {
      switched = true;
      int temp = sub[i];
      sub[i] = sub[i + 1];
      sub[i + 1] = temp;
    } 
    else if (sub[i] == sub[i + 1]) return true;
  }
  if (!switched) return false; //We have not sorted the array and found zero dups

  return hasRepeatedElements(sub); //The recursive bit

}

如果你认为这看起来很匆忙,我有机会赶上。基本的原则在那里,有人在这里几乎可以肯定地改进代码:)

希望有所帮助。

答案 4 :(得分:0)

如果必须递归该签名......

您还可以对数组进行排序并比较前两个元素。然后使用元素[1..n]进行递归调用。

答案 5 :(得分:0)

如果您不喜欢排序,那么此解决方案无需排序即可解决问题。你应该能够提高效率。

boolean hasRepeatedElements(int[] v) 
{
    if ( v . length <= 1 )
    {
        return ( false ) ;
    }
    int k = RANDOM . nextInt ( v . length ) ;
    int leftLength = v . length / 2 ;
    int [ ] left = new int [ leftLength ] ;
    int rightLength = v . length - l ;
    int [ ] rightLength = new int [ rightLength ] ;
    int i , l , r ;
    for ( i = 0 , l = 0 , r = 0 ; i < v . length ; i ++ )
    {
        if ( ( v [ i ] < v [ k ] ) & ( l < leftLength ) )
        {
            left [ l ] = v [ i ] ;
            l ++ ;
        }
        else if ( ( v [ i ] >= v [ k ] ) & ( r < rightLength ) )
        {
            right [ r ] = v [ i ] ;
            r ++ ;
        }
        else
        {
            return ( hasRepeatedElements ( v ) ) ;
        }
    }
    if ( hasRepeatedElements ( left ) ) { return ( true ) ; }
    if ( hasRepeatedElements ( right ) ) { return ( true ) ; }
    return ( false ) ;
}

此解决方案效率不高,但它使用递归,并且完全遵循方法签名。

static java . util . Random RANDOM = new java . util . Random ( ) ;

boolean hasRepeatedElements(int[] v) 
{
     int s = Random . nextInt ( v . length ) ;
     int t = Random . nextInt ( v . length ) ;
     int temp = v[s] ;
     v[s] = v[t] ;
     v[t] = temp ;
     for ( int i = 0 ; i < v . length - 1 ; i ++ )
     {
          if ( v[i]==v[i+1] ) { return true ; }
          else if ( v[i]>v[i+1] { return hasRepeatedElements ( v ) ; }
     }
     return false ;
}