93

我在接受微软采访时遇到了这个问题。

给定一个随机整数数组,用 C 语言编写一个算法,删除重复数字并返回原始数组中的唯一数字。

例如输入:{4, 8, 4, 1, 1, 2, 9} 输出:{4, 8, 1, 2, 9, ?, ?}

一个警告是,预期的算法不应该要求首先对数组进行排序。并且当一个元素被删除时,以下元素也必须向前移动。无论如何,数组尾部元素向前移动的元素的值可以忽略不计。

更新:结果必须在原始数组中返回,并且不应使用辅助数据结构(例如哈希表)。但是,我想订单保存是没有必要的。

更新2:对于那些想知道为什么这些不切实际的限制的人,这是一个面试问题,所有这些限制都在思考过程中进行了讨论,以了解我如何提出不同的想法。

4

34 回答 34

136

我女朋友建议的解决方案是归并排序的一种变体。唯一的修改是在合并步骤期间,只需忽略重复的值。这个解决方案也是 O(n log n)。在这种方法中,排序/重复删除结合在一起。但是,我不确定这是否有什么不同。

于 2009-10-07T18:00:27.853 回答
49

我之前在 SO 上发布过一次,但我会在这里复制它,因为它非常酷。它使用散列,在适当的位置构建类似于散列集的东西。它保证在腋窝空间中是 O(1)(递归是尾调用),并且通常是 O(N) 时间复杂度。算法如下:

  1. 取数组的第一个元素,这将是哨兵。
  2. 尽可能对数组的其余部分重新排序,以使每个元素都位于与其哈希对应的位置。完成此步骤后,将发现重复项。将它们设置为哨兵。
  3. 将索引等于散列的所有元素移动到数组的开头。
  4. 将所有等于 sentinel 的元素(数组的第一个元素除外)移动到数组的末尾。
  5. 正确散列的元素和重复元素之间剩下的将是由于冲突而无法放入与其散列对应的索引中的元素。递归处理这些元素。

这可以证明是 O(N),前提是在散列中没有病态场景:即使没有重复,每次递归也会消除大约 2/3 的元素。每个级别的递归都是 O(n),其中小的 n 是剩余元素的数量。唯一的问题是,在实践中,当重复项很少时,它比快速排序要慢,即很多冲突。然而,当有大量重复时,它的速度惊人地快。

编辑:在 D 的当前实现中,hash_t 是 32 位。这个算法的所有内容都假设在完整的 32 位空间中,哈希冲突非常少(如果有的话)。然而,碰撞可能经常发生在模数空间中。但是,对于任何合理大小的数据集,这个假设很可能是正确的。如果密钥小于或等于 32 位,它可以是它自己的哈希,这意味着在完整的 32 位空间中发生冲突是不可能的。如果它更大,那么您根本无法将足够多的它们放入 32 位内存地址空间中,这将成为一个问题。我假设在 D 的 64 位实现中 hash_t 将增加到 64 位,其中数据集可以更大。此外,如果这确实被证明是一个问题,则可以在每个递归级别更改散列函数。

这是 D 编程语言中的一个实现:

void uniqueInPlace(T)(ref T[] dataIn) {
    uniqueInPlaceImpl(dataIn, 0);
}

void uniqueInPlaceImpl(T)(ref T[] dataIn, size_t start) {
    if(dataIn.length - start < 2)
        return;

    invariant T sentinel = dataIn[start];
    T[] data = dataIn[start + 1..$];

    static hash_t getHash(T elem) {
        static if(is(T == uint) || is(T == int)) {
            return cast(hash_t) elem;
        } else static if(__traits(compiles, elem.toHash)) {
            return elem.toHash;
        } else {
            static auto ti = typeid(typeof(elem));
            return ti.getHash(&elem);
        }
    }

    for(size_t index = 0; index < data.length;) {
        if(data[index] == sentinel) {
            index++;
            continue;
        }

        auto hash = getHash(data[index]) % data.length;
        if(index == hash) {
            index++;
            continue;
        }

        if(data[index] == data[hash]) {
            data[index] = sentinel;
            index++;
            continue;
        }

        if(data[hash] == sentinel) {
            swap(data[hash], data[index]);
            index++;
            continue;
        }

        auto hashHash = getHash(data[hash]) % data.length;
        if(hashHash != hash) {
            swap(data[index], data[hash]);
            if(hash < index)
                index++;
        } else {
            index++;
        }
    }


    size_t swapPos = 0;
    foreach(i; 0..data.length) {
        if(data[i] != sentinel && i == getHash(data[i]) % data.length) {
            swap(data[i], data[swapPos++]);
        }
    }

    size_t sentinelPos = data.length;
    for(size_t i = swapPos; i < sentinelPos;) {
        if(data[i] == sentinel) {
            swap(data[i], data[--sentinelPos]);
        } else {
            i++;
        }
    }

    dataIn = dataIn[0..sentinelPos + start + 1];
    uniqueInPlaceImpl(dataIn, start + swapPos + 1);
}
于 2009-10-07T19:27:25.057 回答
19

一种更有效的实现

int i, j;

/* new length of modified array */
int NewLength = 1;

for(i=1; i< Length; i++){

   for(j=0; j< NewLength ; j++)
   {

      if(array[i] == array[j])
      break;
   }

   /* if none of the values in index[0..j] of array is not same as array[i],
      then copy the current value to corresponding new position in array */

  if (j==NewLength )
      array[NewLength++] = array[i];
}

在这个实现中,不需要对数组进行排序。此外,如果发现重复元素,则无需将其后的所有元素移动一个位置。

这段代码的输出是数组[],大小为 NewLength

在这里,我们从数组中的第二个元素开始,并将它与数组中的所有元素进行比较,直到这个数组。我们持有一个额外的索引变量“NewLength”来修改输入数组。NewLength 变量初始化为 0。

array[1] 中的元素将与 array[0] 进行比较。如果它们不同,则 array[NewLength] 中的值将被 array[1] 修改并增加 NewLength。如果它们相同,则不会修改 NewLength。

所以如果我们有一个数组 [1 2 1 3 1],那么

在“j”循环的第一遍中,array[1] (2) 将与 array0 进行比较,然后将 2 写入 array[NewLength] = array[1],因此 array 将是 [1 2],因为 NewLength = 2

在“j”循环的第二遍中,array[2] (1) 将与 array0 和 array1 进行比较。这里由于 array[2] (1) 和 array0 是相同的循环将在这里中断。所以数组将是 [1 2] 因为 NewLength = 2

等等

于 2009-10-07T18:35:23.707 回答
19

怎么样:

void rmdup(int *array, int length)
{
    int *current , *end = array + length - 1;

    for ( current = array + 1; array < end; array++, current = array + 1 )
    {
        while ( current <= end )
        {
            if ( *current == *array )
            {
                *current = *end--;
            }
            else
            {
                current++;
            }
        }
    }
}

应该是 O(n^2) 或更小。

于 2009-10-07T17:39:05.977 回答
19

如果您正在寻找优越的 O 表示法,那么使用 O(n log n) 排序对数组进行排序,然后进行 O(n) 遍历可能是最好的路线。没有排序,您正在查看 O(n^2)。

编辑:如果你只是在做整数,那么你也可以做基数排序来得到 O(n)。

于 2009-10-07T16:51:33.777 回答
11

1. 使用 O(1) 额外空间,在 O(n log n) 时间内

这是可能的,例如:

  • 首先进行就地 O(n log n) 排序
  • 然后遍历列表一次,将 every 的第一个实例写回列表的开头

我相信 ejel 的合作伙伴是正确的,最好的方法是使用简化的合并步骤进行就地合并排序,如果你是这样的话,这可能是问题的意图。编写一个新的库函数来尽可能高效地执行此操作,而无法改进输入,并且在某些情况下,根据输入的种类,在没有哈希表的情况下这样做会很有用。但我还没有真正检查过这个。

2. 在 O(n) 时间内使用 O(lots) 额外空间

  • 声明一个足够大的零数组以容纳所有整数
  • 遍历数组一次
  • 对于每个整数,将相应的数组元素设置为 1。
  • 如果它已经是 1,则跳过该整数。

这仅在几个有问题的假设成立时才有效:

  • 可以廉价地将内存归零,或者整数的大小与它们的数量相比很小
  • 您很高兴向您的操作系统询问 256^sizepof(int) 内存
  • 如果它是巨大的,它会非常有效地为你缓存它

这是一个糟糕的答案,但如果你有很多输入元素,但它们都是 8 位整数(甚至可能是 16 位整数),那可能是最好的方法。

3. O(little)-ish 额外空间,O(n)-ish 时间

与 #2 一样,但使用哈希表。

4. 明确的方式

如果元素的数量很少,如果其他代码写得更快,读得更快,那么写一个合适的算法就没用了。

例如。遍历每个唯一元素(即第一个元素、第二个元素(第一个元素的重复项已被删除)等)的数组,删除所有相同的元素。O(1) 额外空间,O(n^2) 时间。

例如。使用执行此操作的库函数。效率取决于你有哪些容易获得的。

于 2009-10-09T09:40:03.407 回答
7

好吧,它的基本实现非常简单。遍历所有元素,检查其余元素中是否存在重复项,然后将其余元素移到它们之上。

这是非常低效的,您可以通过输出或排序/二叉树的辅助数组来加速它,但这似乎是不允许的。

于 2009-10-07T16:54:46.660 回答
6

如果您愿意牺牲内存,您可以在一次遍历中完成此操作。您可以简单地计算您是否在哈希/关联数组中看到了一个整数。如果您已经看到了一个数字,请随时将其删除,或者更好的是,将您未见过的数字移动到新数组中,避免原始数组中的任何移动。

在 Perl 中:

foreach $i (@myary) {
    if(!defined $seen{$i}) {
        $seen{$i} = 1;
        push @newary, $i;
    }
}
于 2009-10-07T16:55:08.060 回答
6

如果您被允许使用 C++,则调用 tostd::sort后调用 tostd::unique将为您提供答案。排序的时间复杂度为 O(N log N),唯一遍历的时间复杂度为 O(N)。

如果 C++ 不在讨论范围内,那么没有任何东西可以阻止这些相同的算法用 C 编写。

于 2009-10-07T17:01:01.123 回答
5

函数的返回值应该是唯一元素的数量,它们都存储在数组的前面。如果没有这些附加信息,您甚至都不知道是否有任何重复。

外循环的每次迭代都会处理数组的一个元素。如果它是唯一的,它会留在数组的前面,如果它是重复的,它会被数组中最后一个未处理的元素覆盖。该解决方案在 O(n^2) 时间内运行。

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

size_t rmdup(int *arr, size_t len)
{
  size_t prev = 0;
  size_t curr = 1;
  size_t last = len - 1;
  while (curr <= last) {
    for (prev = 0; prev < curr && arr[curr] != arr[prev]; ++prev);
    if (prev == curr) {
      ++curr;
    } else {
      arr[curr] = arr[last];
      --last;
    }
  }
  return curr;
}

void print_array(int *arr, size_t len)
{
  printf("{");
  size_t curr = 0;
  for (curr = 0; curr < len; ++curr) {
    if (curr > 0) printf(", ");
    printf("%d", arr[curr]);
  }
  printf("}");
}

int main()
{
  int arr[] = {4, 8, 4, 1, 1, 2, 9};
  printf("Before: ");
  size_t len = sizeof (arr) / sizeof (arr[0]);
  print_array(arr, len);
  len = rmdup(arr, len);
  printf("\nAfter: ");
  print_array(arr, len);
  printf("\n");
  return 0;
}
于 2012-11-20T02:49:02.660 回答
4

这是一个Java版本。

int[] removeDuplicate(int[] input){

        int arrayLen = input.length;
        for(int i=0;i<arrayLen;i++){
            for(int j = i+1; j< arrayLen ; j++){
                if(((input[i]^input[j]) == 0)){
                    input[j] = 0;
                }
                if((input[j]==0) && j<arrayLen-1){
                        input[j] = input[j+1];
                        input[j+1] = 0;
                    }               
            }
        }       
        return input;       
    }
于 2012-04-27T04:05:44.307 回答
3

这是我的解决方案。

///// find duplicates in an array and remove them

void unique(int* input, int n)
{
     merge_sort(input, 0, n) ;

     int prev = 0  ;

     for(int i = 1 ; i < n ; i++)
     {
          if(input[i] != input[prev])
               if(prev < i-1)
                   input[prev++] = input[i] ;                         
     }
}
于 2012-10-07T11:42:29.003 回答
2

这可以通过 O(N log N) 算法一次性完成,无需额外存储。

从元素继续a[1]a[N]。在每个阶段i, 左边的所有元素都a[i]包含一个有序的元素a[0]a[j]。同时,第二个索引j,最初为 0,跟踪堆的大小。

检查并将其插入到a[i]堆中,该堆现在占据. 在插入元素时,如果遇到具有相同值的重复元素,则不要插入到堆中(即丢弃它);否则将其插入堆中,该堆现在增长一个元素,现在包括to和 increment 。a[0]a[j+1]a[k]a[i]a[0]a[j+1]j

以这种方式继续,递增i直到所有数组元素都被检查并插入到堆中,最终占用a[0]a[j]. j是堆的最后一个元素的索引,堆只包含唯一的元素值。

int algorithm(int[] a, int n)
{
    int   i, j;  

    for (j = 0, i = 1;  i < n;  i++)
    {
        // Insert a[i] into the heap a[0...j]
        if (heapInsert(a, j, a[i]))
            j++;
    }
    return j;
}  

bool heapInsert(a[], int n, int val)
{
    // Insert val into heap a[0...n]
    ...code omitted for brevity...
    if (duplicate element a[k] == val)
        return false;
    a[k] = val;
    return true;
}

查看示例,这并不是所要求的,因为结果数组保留了原始元素顺序。但是如果放宽这个要求,上面的算法应该可以解决问题。

于 2009-10-08T01:35:35.970 回答
2

一个数组显然应该从右到左“遍历”以避免不必要地来回复制值。

如果您有无限的内存,您可以为sizeof(type-of-element-in-array) / 8字节分配一个位数组,让每个位表示您是否已经遇到相应的值。

如果你不这样做,我想不出比遍历数组并将每个值与它后面的值进行比较,然后如果发现重复,则完全删除这些值更好的方法。这是在O(n^2)(或O((n^2-n)/2) )附近的某个地方。

IBM 有一篇关于有点接近主题的文章。

于 2009-10-07T16:52:19.843 回答
2

让我们来看看:

  • O(N) 通过找到最小/最大分配
  • 找到的位数组
  • O(N) 通过交换重复到结束。
于 2009-10-07T16:59:01.437 回答
1

在Java中我会这样解决它。不知道怎么用 C 写这个。

   int length = array.length;
   for (int i = 0; i < length; i++) 
   {
      for (int j = i + 1; j < length; j++) 
      {
         if (array[i] == array[j]) 
         {
            int k, j;
            for (k = j + 1, l = j; k < length; k++, l++) 
            {
               if (array[k] != array[i]) 
               {
                  array[l] = array[k];
               }
               else
               {
                  l--;
               }
            }
            length = l;
         }
      }
   }
于 2009-10-07T19:02:07.667 回答
1

这是天真的 (N*(N-1)/2) 解决方案。它使用恒定的额外空间并保持原始顺序。它类似于@Byju 的解决方案,但不使用任何if(){}块。它还避免了将元素复制到自身上。

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

int numbers[] = {4, 8, 4, 1, 1, 2, 9};
#define COUNT (sizeof numbers / sizeof numbers[0])

size_t undup_it(int array[], size_t len)
{
size_t src,dst;

  /* an array of size=1 cannot contain duplicate values */
if (len <2) return len; 
  /* an array of size>1 will cannot at least one unique value */
for (src=dst=1; src < len; src++) {
        size_t cur;
        for (cur=0; cur < dst; cur++ ) {
                if (array[cur] == array[src]) break;
                }
        if (cur != dst) continue; /* found a duplicate */

                /* array[src] must be new: add it to the list of non-duplicates */
        if (dst < src) array[dst] = array[src]; /* avoid copy-to-self */
        dst++;
        }
return dst; /* number of valid alements in new array */
}

void print_it(int array[], size_t len)
{
size_t idx;

for (idx=0; idx < len; idx++)  {
        printf("%c %d", (idx) ? ',' :'{' , array[idx] );
        }
printf("}\n" );
}

int main(void) {    
    size_t cnt = COUNT;

    printf("Before undup:" );    
    print_it(numbers, cnt);    

    cnt = undup_it(numbers,cnt);

    printf("After undup:" );    
    print_it(numbers, cnt);

    return 0;
}
于 2013-10-12T12:00:50.823 回答
1

下面的呢?

int* temp = malloc(sizeof(int)*len);
int count = 0;
int x =0;
int y =0;
for(x=0;x<len;x++)
{
    for(y=0;y<count;y++)
    {
        if(*(temp+y)==*(array+x))
        {
            break;
        }
    }
    if(y==count)
    {
        *(temp+count) = *(array+x);
        count++;
    }
}
memcpy(array, temp, sizeof(int)*len);

我尝试声明一个临时数组并将元素放入其中,然后将所有内容复制回原始数组。

于 2010-06-10T12:38:25.357 回答
1

查看问题后,这是我的delphi方式,可能会有所帮助

var
A: Array of Integer;
I,J,C,K, P: Integer;
begin
C:=10;
SetLength(A,10);
A[0]:=1; A[1]:=4; A[2]:=2; A[3]:=6; A[4]:=3; A[5]:=4;
A[6]:=3; A[7]:=4; A[8]:=2; A[9]:=5;

for I := 0 to C-1 do
begin
  for J := I+1 to C-1 do
    if A[I]=A[J] then
    begin
      for K := C-1 Downto J do
        if A[J]<>A[k] then
        begin
          P:=A[K];
          A[K]:=0;
          A[J]:=P;
          C:=K;
          break;
        end
        else
        begin
          A[K]:=0;
          C:=K;
        end;
    end;
end;

//tructate array
setlength(A,C);
end;
于 2011-05-12T03:05:10.497 回答
1

以下示例应该可以解决您的问题:

def check_dump(x):
   if not x in t:
      t.append(x)
      return True

t=[]

output = filter(check_dump, input)

print(output)
True
于 2012-06-14T10:02:55.187 回答
1
import java.util.ArrayList;


public class C {

    public static void main(String[] args) {

        int arr[] = {2,5,5,5,9,11,11,23,34,34,34,45,45};

        ArrayList<Integer> arr1 = new ArrayList<Integer>();

        for(int i=0;i<arr.length-1;i++){

            if(arr[i] == arr[i+1]){
                arr[i] = 99999;
            }
        }

        for(int i=0;i<arr.length;i++){
            if(arr[i] != 99999){

                arr1.add(arr[i]);
            }
        }

        System.out.println(arr1);
}
    }
于 2013-08-07T02:54:36.130 回答
0

binary tree the disregards duplicates在-中插入所有元素O(nlog(n))。然后通过遍历 - 将它们全部提取回数组中O(n)。我假设您不需要订单保存。

于 2009-10-07T19:22:35.360 回答
0

在 JAVA 中,

    Integer[] arrayInteger = {1,2,3,4,3,2,4,6,7,8,9,9,10};

    String value ="";

    for(Integer i:arrayInteger)
    {
        if(!value.contains(Integer.toString(i))){
            value +=Integer.toString(i)+",";
        }

    }

    String[] arraySplitToString = value.split(",");
    Integer[] arrayIntResult = new Integer[arraySplitToString.length];
    for(int i = 0 ; i < arraySplitToString.length ; i++){
        arrayIntResult[i] = Integer.parseInt(arraySplitToString[i]);
    }

输出:{ 1, 2, 3, 4, 6, 7, 8, 9, 10}

希望这会有所帮助

于 2012-06-23T15:25:50.367 回答
0

这可以通过单次完成,输入列表中的整数个数在 O(N) 时间内完成,唯一整数个数的存储时间为 O(N)。

从前到后遍历列表,将两个指针“dst”和“src”初始化为第一项。从“看到的整数”的空哈希表开始。如果 src 处的整数不存在于散列中,则将其写入 dst 处的槽并增加 dst。将 src 处的整数添加到哈希中,然后增加 src。重复直到 src 通过输入列表的末尾。

于 2009-10-07T17:06:38.023 回答
0

使用布隆过滤器进行散列。这将非常显着地减少内存开销。

于 2012-04-03T10:02:20.933 回答
0

创建一个BinarySearchTree具有 O(n) 复杂度的。

于 2012-06-14T09:05:40.610 回答
0

给定一个包含 n 个元素的数组,编写一个算法以在 O(nlogn) 时间内从数组中删除所有重复项

Algorithm delete_duplicates (a[1....n])
//Remove duplicates from the given array 
//input parameters :a[1:n], an array of n elements.

{

temp[1:n]; //an array of n elements. 

temp[i]=a[i];for i=1 to n

 temp[i].value=a[i]

temp[i].key=i

 //based on 'value' sort the array temp.

//based on 'value' delete duplicate elements from temp.

//based on 'key' sort the array temp.//construct an array p using temp.

 p[i]=temp[i]value

  return p.

使用“键”在输出数组中维护其他元素。考虑键的长度为 O(n),对键和值执行排序所需的时间为 O(nlogn)。所以从数组中删除所有重复项所花费的时间是 O(nlogn)。

于 2015-03-13T02:29:42.690 回答
0

首先,您应该创建一个数组check[n],其中 n 是您想要避免重复的数组元素的数量,并将每个元素(检查数组的)的值设置为等于 1。使用 for 循环遍历数组重复,说它的名字是arr,并在 for 循环中写下:

{
    if (check[arr[i]] != 1) {
        arr[i] = 0;
    }
    else {
        check[arr[i]] = 0;
    }
}

这样,您将每个重复项设置为零。所以剩下要做的就是遍历arr数组并打印不等于零的所有内容。订单保持不变,需要线性时间 (3*n)。

于 2014-06-22T23:49:12.350 回答
0

这就是我所拥有的,尽管它错位了我们可以按升序或降序排序以修复它的顺序。

#include <stdio.h>
int main(void){
int x,n,myvar=0;
printf("Enter a number: \t");
scanf("%d",&n);
int arr[n],changedarr[n];

for(x=0;x<n;x++){
    printf("Enter a number for array[%d]: ",x);
    scanf("%d",&arr[x]);
}
printf("\nOriginal Number in an array\n");
for(x=0;x<n;x++){
    printf("%d\t",arr[x]);
}

int i=0,j=0;
// printf("i\tj\tarr\tchanged\n");

for (int i = 0; i < n; i++)
{
    // printf("%d\t%d\t%d\t%d\n",i,j,arr[i],changedarr[i] );
    for (int j = 0; j <n; j++)
    {   
        if (i==j)
        {
            continue;

        }
        else if(arr[i]==arr[j]){
            changedarr[j]=0;

        }
        else{
            changedarr[i]=arr[i];

        }
    // printf("%d\t%d\t%d\t%d\n",i,j,arr[i],changedarr[i] );
    }
    myvar+=1;
}
// printf("\n\nmyvar=%d\n",myvar);
int count=0;
printf("\nThe unique items:\n");
for (int i = 0; i < myvar; i++)
{
        if(changedarr[i]!=0){
            count+=1;
            printf("%d\t",changedarr[i]);   
        }
}
    printf("\n");
}
于 2016-02-04T17:02:18.043 回答
-1

这里写的一些答案非常简单(O(n ^ 2)或在O(NlogN)中排序和遍历),我假设这不是微软面试中所期望的。显然,任何高于 O(n) 的答案都不是他们想要的。更新声明不应该有任何辅助数据结构,因此任何有一个(哈希表、树、位数组或其他)的答案都不应该是有效的解决方案。

如果您可以分配额外的内存,那么 Jeff B 的答案可能是最简单的方法。对于此类问题,我有一个很好的答案,但 MAXINT 需要受数组大小的限制。(示例:大小为 100 的数组可能包含 1 到 100 之间的任何数字。删除 dups 作为原始问题)

在 O(n) 时间和 O(1) 内存中对此的答案是:

// FLAG ALL DUPS IN THE ORIGIN ARRAY
int maxNumInArray = findMaxNumInArray(arr);
int dup = findMinNumInArray(arr) - 1;
for (int i=0; i < arrLength; ++i) {
    int seekIndex = arr[i] % (maxNumInArray+1);
    if (arr[seekIndex] > maxNumInArray)
        arr[i] = dup; // invalidate index
    else
        arr[seekIndex] = arr[seekIndex] + maxNumInArray;
}

// REMOVE EMPTY SPACES
int i = 0;
int j = arrLength(arr)-1;
while (i<j) {
    while (arr[i] != dup)
        ++i;
    while (arr[j] == dup)
        --j;
    swap(arr[i], arr[j]);
}

如果您不知道界限,我的答案没有用,但您可以尝试使用它。哦,这个特定的变化不适用于负数,但修复它不是问题。

于 2009-10-07T18:56:37.130 回答
-1

对于想要在 C++ 中获得简单解决方案的人:

int* rmdup(int path[], int start, int end, int& newEnd) {
    int ret[100];
newEnd = end;
int j = start;

for (int i = start; i < end; i++) {
    if (path[i] == path[i+1]) {
    newEnd--;
        continue;
    }
    ret[j++] = path[i];
}

ret[j++] = path[end];

for(int i = start; i <= newEnd; i++)
     path[i] = ret[i];
}
于 2013-11-06T02:54:27.747 回答
-1

如果你有一个好的 DataStructure 可以快速判断它是否包含整数,那就太酷了。也许是某种树。

DataStructure elementsSeen = new DataStructure();
int elementsRemoved = 0;
for(int i=0;i<array.Length;i++){
  if(elementsSeen.Contains(array[i])
    elementsRemoved++;
  else
    array[i-elementsRemoved] = array[i];
}
array.Length = array.Length - elementsRemoved;
于 2009-10-07T17:02:59.327 回答
-2

只需获取一个变量x=arr[0]并通过遍历其余元素进行异或操作。如果一个元素重复了,那么 x 将变为零。

这样我们就知道元素之前已经重复了。这也只需要o(n)扫描原始数组中的所有元素。

于 2014-11-13T04:14:51.927 回答
-2
Integer[] arrayInteger = {1,2,3,4,3,2,4,6,7,8,9,9,10}; 

Set set = new HashSet();
for(Integer i:arrayInteger)
set.add(i);

System.out.println(set);
于 2012-08-30T12:45:26.913 回答