QuickSort和Hash Table在Sum題目中的應用

來源:互聯網
上載者:User
今天遇到了一道難題.題目如下:
Sum
Time limit: 30 Seconds Memory limit: 32768K Bytes
Submitted: 375 Accepted: 44

Sum

Mr. Jojer is given n numbers and an extra integer x, he wants to know whether there are two numbers whose sum is x.

Input

The input file contains several test cases. The first line of each test case contains two integers, n(<=1000001) and x. From the next line of each test case, there are n numbers.

Output

Each test case corresponds to a line in the output, which is either "YES" if there exists an answer or "NO" if not.

Sample Input

3 31 2 32 31 3

Sample Output

YES
NO

Submit your solution

從題目的限制條件可以看出,要求要在1000001多個整數中尋找兩個其和為X的整數,其計算量是十分巨大的.而題目要求的是30秒中完成一批數目的測試(幾組).如果採用一般的迴圈2階相加比較,是現在完不成的.我這裡有兩套解決辦法.

1.以記憶體換速度.
在為了提高運行速度的問題上,首先就應該想到的是以空間代價換取時間上的代價.最能體現這點的就是我們資料結構中所學習的Hash表.Hash表尋找速度十分快,可能我們這裡如何把Hash表應用進來呢?我採用了比較笨的辦法.
迴圈每組數中的每個元素,首先檢查其值是否存在Hash表中,如果存在,說明"YES"。否則將其 X - 元素 的值插入一個Hash表。那麼這樣下去,我只需要一個1階的演算法就能完成。不過這個Hash表十分巨大。不過,我們只需要把在一般範圍內的整數放進Hash表記錄,如果數值的範圍超過了Hash能表示的範圍,就單獨出來存放在一個線性表中。
下面是我已經調試通過,並且在ACM Online Judge上Accpeted的來源程式。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_N 3000002
long  integers[MAX_N];

char  regularTab[MAX_N];
long  extendTab[MAX_N];
long  numExt;

long n;
long x;

void insertTab(int a);
int  lookup(int a);

int main()
{
 long i,j;
 long m;
 int Yes;
 while(scanf("%ld%ld",&n,&x) == 2)
 {
  memset(regularTab,0,MAX_N);
  memset(extendTab,0,MAX_N*sizeof(long));
  numExt = 0;
  Yes = 0;

  for(i=0; i<n; i++)
  {
   scanf("%ld",&integers[i]);
  }

  for(i=0;i<n;i++)
  {
   if(lookup(integers[i]))
   {
    printf("YES/n");
    i = n;
    Yes = 1;
    break;
   }
   else
   {
    insertTab(x-integers[i]);
   }
  }
  if(Yes == 0)
   printf("NO/n");
 }

 return 1;
}

void insertTab(int a)
{
 if(a > -MAX_N/2 && a < MAX_N/2)
 {
  regularTab[a+MAX_N/2] = 1;
 }
 else
 {
  extendTab[numExt++] = a;
 }
}

int lookup(int a)
{
 if(a > -MAX_N/2 && a < MAX_N/2)
 {
  return regularTab[a+MAX_N/2];
 }
 else
 {
  long i;
  for(i=0;i<numExt; i++)
  {
   if(extendTab[i] == a)
    return 1;
  }
  return 0;
 }
}

2.使用QuickSort和qsort函數
快速排序的演算法不用在這裡多講了。在C語言的stdlib.h中已經提供了一個彙編層級的qsort函數。這道題目使用快速排序的辦法就是讓所有的數列先排序,然後再進行尋找。雖然排序也是二階演算法,但是由於QuickSort的特殊性,使得排序的過程還是比較快,一旦排序完成後,根據X進行二分尋找,幾步就可以完成了。具體的實現程式我這裡沒有。不過我覺得qsort的函數使用是十分重要的,所以我從msdn上抄襲了qsort函數的範例程式碼。

void qsort(   void *base,   size_t num,   size_t width,   int (__cdecl *compare )(const void *, const void *) );
Example
// crt_qsort.c// arguments: every good boy deserves favor/* This program reads the command-line * parameters and uses qsort to sort them. It * then displays the sorted arguments. */#include <stdlib.h>#include <string.h>#include <stdio.h>int compare( const void *arg1, const void *arg2 );int main( int argc, char **argv ){   int i;   /* Eliminate argv[0] from sort: */   argv++;   argc--;   /* Sort remaining args using Quicksort algorithm: */   qsort( (void *)argv, (size_t)argc, sizeof( char * ), compare );   /* Output sorted list: */   for( i = 0; i < argc; ++i )      printf( " %s", argv[i] );   printf( "/n" );}int compare( const void *arg1, const void *arg2 ){   /* Compare all of both strings: */   return _stricmp( * ( char** ) arg1, * ( char** ) arg2 );}
Output
 boy deserves every favor good

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.