天天看點

關于數組的幾道面試題

1.求子數組的最大和

題目:輸入一個整形數組,數組裡有正數也有負數。數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個和。求所有子數組的和的最大值。要求時間複雜度為O(n)。

        例如輸入的數組為1, -2, 3, 10, -4, 7, 2, -5,和最大的子數組為3, 10, -4, 7, 2,是以輸出為該子數組的和18。

        如果不考慮時間複雜度,我們可以枚舉出所有子數組并求出他們的和。不過非常遺憾的是,由于長度為n的數組有O(n2),具體是n*(n+1)/2個子數組;而且求一個長度為n的數組的和的時間複雜度為O(n)。是以這種思路的時間是O(n3)。

解題思路:很容易了解,當我們加上一個正數時,和會增加;當我們加上一個負數時,和會減少。如果目前得到的和是個負數,那麼這個和在接下來的累加中應該抛棄并重新清零,不然的話這個負數将會減少接下來的和。

#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <malloc.h> int main() {     int *ip;     int j,length,max,sum;     int start1 = 0 ,start2 = 0;          printf("Please enter the array's length:");     scanf("%d",&length);     if((ip = (int*)malloc(length*sizeof(int)))==NULL)     {             fprintf(stderr,"Malloc memory failed !");             exit(1);     }     printf("Enter eath element:");     for(j = 0; j < length ; j ++)     scanf("%d",ip+j);     max = INT_MIN;     for(sum = j = 0; j < length; j ++)     {             sum += *(ip+j);             if(max < sum)             {                     start1 = start2;                     max = sum;             }             if(sum < 0){                     start2 = j+1;                     sum = 0;                                  }      }      for(j = start1,sum = 0; sum != max; j ++)             sum += *(ip+j);      printf("\nThe subsequence from %d to %d,max sum is %d\n",start1,j-1,max);   return 0; }

2.求兩個有序數組的共同元素

給定兩個含有n個元素的有序(非降序)整型數組a和b,求出其共同元素,比如

a = 0, 1, 2, 3, 4

b = 1, 3, 5, 7, 9

輸出 1, 3

分析

充分利用數組有序的性質,用兩個指針i和j分别指向a和b,比較a[i]和b[j],根據比較結果移動指針,則有如下三種情況

1. a[i] < b[j],則i增加1,繼續比較

2. a[i] == b[j],則i和j皆加1,繼續比較

3. a[i] < b[j],則j加1,繼續比較

重複以上過程直到i或j到達數組末尾。

// 找出兩個數組的共同元素 void FindCommon(int* a, int* b, int n) {     int i = 0;     int j = 0 ;     while (i < n && j < n)     {         if (a[i] < b[j])             ++i ;         else if(a[i] == b[j])         {             cout << a[i] << endl ;             ++i ;             ++j ;         }         else// a[i] > b[j]             ++j ;     } }

3.數組的循環右移

【題目】有一個整數數組,現要求實作這個整數數組的循環右移。如:1,2,3,4,5 則循環右移兩位後結果是:4,5,1,2,3。

void RightCircleShift_04(int buffer[],int shift) {     shift %= ARRSIZE;     ReverseArray(buffer,1,ARRSIZE);     ReverseArray(buffer,1,shift);     ReverseArray(buffer,shift+1,ARRSIZE); } void ReverseArray(int buffer[],int start,int end) {     int i,tt;       if(end > ARRSIZE)        return;       start -= 1;     end -= 1;     while(start < end)     {        tt = buffer[start];        buffer[start++] = buffer[end];        buffer[end--] = tt;     } }

   1、先将整個數組反轉。

2、然後再反轉前shift個元素。

3、接着再反轉後N-shift個元素

4.去除數組中重複數字問題