各大公司筆試面試題之數據結構與算法


1. 把二元查找樹轉變成排序的雙向鏈表

  1. //基本思想:假設根的左右兩棵子樹都已經轉爲鏈表,則只需將根指向左孩子的鏈指向左鏈表的最後一個節點  
  2. //將根指向右孩子的鏈指向右鏈表的第一個節點  
  3. #include <iostream>  
  4. using namespace std;  
  5.   
  6. struct node  
  7. {  
  8.     int value;  
  9.     node *left;  
  10.     node *right;  
  11. };  
  12.   
  13. void treeToList(node *root)  
  14. {  
  15.     if(!root)  
  16.         return;  
  17.     treeToList(root->left);  
  18.     treeToList(root->right);  
  19.     node *cur;  
  20.     if(root->left)  
  21.     {  
  22.         cur = root->left;  
  23.         while(cur->right)  
  24.         {  
  25.             cur = cur->right;  
  26.         }  
  27.         root->left = cur;  
  28.         cur->right = root;  
  29.     }  
  30.     if(root->right)  
  31.     {  
  32.         cur = root->right;  
  33.         while(cur->left)  
  34.         {  
  35.             cur = cur->left;  
  36.         }  
  37.         root->right = cur;  
  38.         cur->left = root;  
  39.     }  
  40. }  
  41.   
  42. node * treeToListInterface(node *root)  
  43. {  
  44.     treeToList(root);  
  45.     node *cur = root;  
  46.     if(cur)  
  47.     {  
  48.         while(cur->left)  
  49.             cur = cur->left;  
  50.     }  
  51.     return cur;  
  52. }  
  53.   
  54. node * build_tree()  
  55. {  
  56.     int a;  
  57.     cin >> a;  
  58.     if(a == 0)  
  59.     {  
  60.         return NULL;  
  61.     }  
  62.     node *root = new node();  
  63.     root->value = a;  
  64.     root->left = build_tree();  
  65.     root->right = build_tree();  
  66.     return root;  
  67. }  
  68.   
  69. void displayList(node *head)  
  70. {  
  71.     node *cur = head;  
  72.     while(cur)  
  73.     {  
  74.         cout  << cur->value << " ";  
  75.         cur = cur->right;  
  76.     }  
  77.     cout << endl;  
  78. }  
  79.   
  80. int main()  
  81. {  
  82.     node *root = build_tree();  
  83.     root = treeToListInterface(root);  
  84.     displayList(root);  
  85.     return 0;  
  86. }  





2. 設計包含 min 函數的棧。
定義棧的數據結構,要求添加一個 min 函數,能夠得到棧的最小元素。

要求函數 min 、 push 以及 pop 的時間複雜度都是 O(1) 。

  1. //基本思想:增加一個輔助棧,輔助棧的棧頂元素既是當前最小元素的下標。  
  2. //每次出棧時,同時對輔助棧也執行pop操作。  
  3. #include <iostream>  
  4. using namespace std;  
  5. const int N = 100;  
  6. class Stack  
  7. {  
  8. private:  
  9.     int a[N];  
  10.     int top;  
  11.     int b[N];  
  12.     int btop;  
  13. public:  
  14.     Stack():top(-1),btop(-1){}  
  15.     void push(int e){  
  16.         a[++top] = e;  
  17.         if(btop == -1)  
  18.         {  
  19.             b[++btop] = 0;  
  20.         }else  
  21.         {  
  22.             b[btop + 1] = e < a[b[btop]] ? top: b[btop];  
  23.             btop++;  
  24.         }  
  25.     }  
  26.     void pop()  
  27.     {  
  28.         --top;  
  29.         --btop;  
  30.     }  
  31.     int min()  
  32.     {  
  33.         return a[b[btop]];  
  34.     }  
  35. };  
  36.   
  37. int main()  
  38. {  
  39.     Stack test;  
  40.     test.push(1);  
  41.     cout << test.min() << endl;  
  42.     test.push(2);  
  43.     cout << test.min() << endl;  
  44.     test.push(4);  
  45.     cout << test.min() << endl;  
  46.     test.push(5);  
  47.     cout << test.min() << endl;  
  48. }  


3. 求子數組的最大和
題目:
輸入一個整形數組,數組裏有正數也有負數。
數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個和。
求所有子數組的和的最大值。要求時間複雜度爲 O(n) 。
例如輸入的數組爲 1, -2, 3, 10, -4, 7, 2, -5 ,和最大的子數組爲 3, 10, -4, 7, 2 ,

  1. //基本思想:dp  
  2. //從後往前思考,從前往後寫代碼。  
  3. //t[i]表示包括a[i]在內的最大子數組之和  
  4. //在處理大小爲i的數組時,先假設大小爲i-1的數組已經處理好  
  5. //則t[i] = t[i - 1] + a[i] > a[i] ? t[i - 1] + a[i] : a[i];  
  6. #include <iostream>  
  7. using namespace std;  
  8.   
  9. const int N =100;  
  10. int MaxSumOfSubArray(int *a, int size)  
  11. {  
  12.     int t[N];  
  13.     t[0] = a[0];  
  14.     for(int i = 1; i < size; i++)  
  15.     {  
  16.         t[i] = t[i - 1] + a[i] > a[i] ? t[i - 1] + a[i] : a[i];  
  17.     }  
  18.     int max = t[0];  
  19.     for(int i = 1; i < size; i++)  
  20.     {  
  21.         max = max > t[i] ? max : t[i];  
  22.     }  
  23.     return max;  
  24. }  
  25.   
  26. int main()  
  27. {  
  28.     int a[8] = { 1, -2, 3, 10, -4, 7, 2, -5 };  
  29.     cout << MaxSumOfSubArray(a, 8);  
  30.   
  31. }  


4. 在二元樹中找出和爲某一值的所有路徑
題目:輸入一個整數和一棵二元樹。
從樹的根結點開始往下訪問一直到葉結點所經過的所有結點形成一條路徑。
打印出和與輸入整數相等的所有路徑。
例如輸入整數 22 和如下二元樹
10
/ \
5 12
/ \
4 7

則打印出兩條路徑: 10, 12 和 10, 5, 7 。
二元樹節點的數據結構定義爲:
struct BinaryTreeNode // a node in the binary tree
{
int m_nValue; // value of node
BinaryTreeNode *m_pLeft; // left child of node
BinaryTreeNode *m_pRight; // right child of node

};

  1. //基本思想:函數的接口、數據結構設計好了,算法也就呼之欲出了。  
  2. //需要隨着回溯而改變的變量應該作爲遞歸函數的形參,可以考慮增加輔助函數  
  3. #include <iostream>  
  4. using namespace std;  
  5. const int N = 100;  
  6. struct BinaryTreeNode // a node in the binary tree  
  7. {  
  8.     int m_nValue; // value of node  
  9.     BinaryTreeNode *m_pLeft; // left child of node  
  10.     BinaryTreeNode *m_pRight; // right child of node  
  11. };  
  12. int path[N];  
  13. int cur = 0;  
  14.   
  15. void findPathRecursively(BinaryTreeNode *root, int value ,int cur)  
  16. {  
  17.     if(!root)  
  18.         return ;  
  19.     if(!root->m_pLeft && !root->m_pLeft)  
  20.     {  
  21.         if(root->m_nValue == value)  
  22.         {  
  23.             path[cur++] = value;  
  24.             for(int i = 0; i < cur; i++)  
  25.                 cout << path[i] << " ";  
  26.             cout << endl;  
  27.         }  
  28.     }  
  29.     else  
  30.     {  
  31.         path[cur++] = root->m_nValue;  
  32.         if(root->m_pLeft)  
  33.         {  
  34.   
  35.             findPathRecursively(root->m_pLeft, value - root->m_nValue, cur);  
  36.         }  
  37.         if(root->m_pRight)  
  38.         {  
  39.   
  40.             findPathRecursively(root->m_pRight, value - root->m_nValue, cur);  
  41.         }  
  42.     }  
  43. }  
  44.   
  45. //這樣設置,path[],cur不能跟着遞歸改變。  
  46. //所以必須使用一個輔助函數  
  47. void findPath(BinaryTreeNode *root, int value)  
  48. {  
  49.     findPathRecursively(root,value,cur);  
  50. }  
  51. BinaryTreeNode * build_tree()  
  52. {  
  53.     int a;  
  54.     cin >> a;  
  55.     if(a == 0)  
  56.     {  
  57.         return NULL;  
  58.     }  
  59.     BinaryTreeNode *root = new BinaryTreeNode();  
  60.     root->m_nValue = a;  
  61.     root->m_pLeft = build_tree();  
  62.     root->m_pRight = build_tree();  
  63.     return root;  
  64. }  
  65.   
  66. int main()  
  67. {  
  68.     BinaryTreeNode *tree = build_tree();  
  69.     findPath(tree, 10);  
  70.   
  71. }  


5. 查找最小的 k 個元素
題目:輸入 n 個整數,輸出其中最小的 k 個。
例如輸入 1 , 2 , 3 , 4 , 5 , 6 , 7 和 8 這 8 個數字,則最小的 4 個數字爲 1 , 2 , 3 和 4 。

  1. //基本思想:先快排  
  2. //有更好的方法,以後有時間再寫  
  3.   
  4.   
  5. #include <iostream>  
  6. #include <ctime>  
  7. using namespace std;  
  8. const int N = 10000;  
  9.   
  10. int partition(int *a, int b, int e)  
  11. {  
  12.     int i = b - 1;  
  13.        
  14.     for(int j = b; j < e; j++)  
  15.     {  
  16.         if(a[j] < a[e])  
  17.         {  
  18.             i++;  
  19.             int tem = a[i];  
  20.             a[i] = a[j];  
  21.             a[j] = tem;  
  22.         }  
  23.     }  
  24.       
  25.     int tem = a[i + 1];  
  26.     a[i + 1] = a[e];  
  27.     a[e] = tem;  
  28.     return i + 1;  
  29.       
  30. }  
  31.   
  32. void qsort(int *a, int b, int e)  
  33. {  
  34.     if(b < e)  
  35.     {  
  36.         int q = partition(a,b,e);  
  37.         qsort(a, b, q-1);  
  38.         qsort(a, q+1, e);  
  39.     }  
  40. }  
  41.   
  42. void fun(int *a, int size, int k)  
  43. {  
  44.     qsort(a, 0, size - 1);  
  45.     for(int i = 0; i < k; i++)  
  46.         cout << a[i] << " ";  
  47.     cout << endl;  
  48. }  
  49. int main()  
  50. {  
  51.     int a[] = {3,4,8,2,1};  
  52.     fun(a, 5, 2);  
  53. }  


第 6 題
轉換字符串格式爲:原來字符串裏的字符+該字符連續出現的個數。

  1. #include <iostream>  
  2. #include <ctime>  
  3. #include <cassert>  
  4. using namespace std;  
  5. const int N = 10000;  
  6. void convertStringFormat(char *str)  
  7. {  
  8.     for(int i = 0, len = strlen(str); i < len; i++)  
  9.     {  
  10.         int count = 1;  
  11.         cout << str[i];  
  12.         while(str[i] == str[i + 1])  
  13.         {  
  14.             count ++;  
  15.             i++;  
  16.         }  
  17.         cout << count;  
  18.     }  
  19. }  
  20. int main()  
  21. {  
  22.     convertStringFormat("1233422222");  
  23.   
  24. }  


第 7 題
微軟亞院之編程判斷倆個鏈表是否相交
給出倆個單向鏈表的頭指針,比如 h1 , h2 ,判斷這倆個鏈表是否相交。
爲了簡化問題,我們假設倆個鏈表均不帶環。

  1. //基本思想:若兩鏈表相交,則它們最終合併爲一條鏈表  
  2.   
  3. #include <iostream>  
  4. #include <ctime>  
  5. using namespace std;  
  6.   
  7. struct node  
  8. {  
  9.     int value;  
  10.     node *next;  
  11. };  
  12.   
  13. void displayList(node *head)  
  14. {  
  15.     node *cur = head;  
  16.     while(cur)  
  17.     {  
  18.         cout  << cur->value << " ";  
  19.         cur = cur->next;  
  20.     }  
  21.     cout << endl;  
  22. }  
  23.   
  24. bool isCross(node *h1, node *h2)  
  25. {  
  26.     node *cur1 = h1, *cur2 = h2;  
  27.     if(!h1 || !h2)  
  28.         return false;  
  29.     while(cur1->next)  
  30.         cur1 = cur1->next;  
  31.     while(cur2->next)  
  32.         cur2 = cur2->next;  
  33.     return cur1 == cur2;  
  34. }  
  35. node * make_link()  
  36. {  
  37.     srand(time(NULL));  
  38.     node *head = new node();  
  39.     node *cur = head;  
  40.     for(int i= 0; i < 10; i++)  
  41.     {  
  42.         cur->value = rand() % 10;  
  43.         cur->next = new node();  
  44.         cur = cur->next;  
  45.     }  
  46.     return head;  
  47. }  
  48.   
  49. int main()  
  50. {  
  51.     node *h1 = make_link();;  
  52.     node *h2 = new node();  
  53.     h2->value = 1;  
  54.     node *tem = h2->next = new node();  
  55.     tem->value = 2;  
  56.     /*tem->next = h1->next->next->next;*/  
  57.     tem->next = NULL;  
  58.   
  59.       
  60.     cout << isCross(h1, h2);  
  61.     return 0;  
  62. }  

第8題:

問題擴展:
1. 如果鏈表可能有環列 ?
2. 如果需要求出倆個鏈表相交的第一個節點列 ?

  1. //擴展2  
  2. //基本思想:若兩鏈表相交,則它們最終合併爲一條鏈表  
  3. //設兩鏈表的長度分別爲l1,l2,使指向長鏈表的指針先走|l1-l2|,  
  4. //然後兩鏈表指針再一起走,它們將到時到達相交節點  
  5.   
  6. #include <iostream>  
  7. #include <ctime>  
  8. using namespace std;  
  9.   
  10. struct node  
  11. {  
  12.     int value;  
  13.     node *next;  
  14. };  
  15.   
  16. void displayList(node *head)  
  17. {  
  18.     node *cur = head;  
  19.     while(cur)  
  20.     {  
  21.         cout  << cur->value << " ";  
  22.         cur = cur->next;  
  23.     }  
  24.     cout << endl;  
  25. }  
  26.   
  27.   
  28. node *firstCrossNode(node *h1, node *h2)  
  29. {  
  30.     node *cur1 = h1, *cur2 = h2;  
  31.       
  32.     if(!h1 || !h2)  
  33.         return NULL;  
  34.     int len1 = 1, len2 = 1;  
  35.     while(cur1->next)  
  36.     {  
  37.         cur1 = cur1->next;  
  38.         len1++;  
  39.     }  
  40.     while(cur2->next)  
  41.     {  
  42.         cur2 = cur2->next;  
  43.         len2++;  
  44.     }  
  45.     if(cur1 != cur2)  
  46.         return NULL;  
  47.   
  48.     cur1 = h1;  
  49.     cur2 = h2;  
  50.     if(len1 > len2)  
  51.     {  
  52.         for(int i = 0; i < len1 - len2; i++)  
  53.         {  
  54.             cur1 = cur1->next;  
  55.         }  
  56.     }  
  57.     else  
  58.     {  
  59.         for(int i = 0; i < len2 - len1; i++)  
  60.         {  
  61.             cur2 = cur2->next;  
  62.         }  
  63.     }  
  64.     while(cur1 != cur2)  
  65.     {  
  66.         cur1 = cur1->next;  
  67.         cur2 = cur2->next;  
  68.     }  
  69.     return cur1;  
  70. }  
  71. node * make_link()  
  72. {  
  73.     srand(time(NULL));  
  74.     node *head = new node();  
  75.     node *cur = head;  
  76.     for(int i= 0; i < 10; i++)  
  77.     {  
  78.         cur->value = rand() % 10;  
  79.         cur->next = new node();  
  80.         cur = cur->next;  
  81.     }  
  82.     return head;  
  83. }  
  84.   
  85. int main()  
  86. {  
  87.     node *h1 = make_link();;  
  88.     node *h2 = new node();  
  89.     h2->value = 1;  
  90.     node *tem = h2->next = new node();  
  91.     tem->value = 2;  
  92.     tem->next = h1->next->next->next;  
  93.     /*tem->next = NULL;*/  
  94.   
  95.       
  96.     cout << firstCrossNode(h1, h2)->value;  
  97.     return 0;  
  98. }  

第9題

將一句話裏的單詞進行倒置,標點符號不倒換。比如“i come from shantou.” -> "santou. from com i"

  1. //基本思想:先整句逆轉,再部分逆轉。  
  2.   
  3. #include <iostream>  
  4. #include <ctime>  
  5. #include <cassert>  
  6. using namespace std;  
  7. const int N = 10000;  
  8. void reverse(char *str, int b, int e)  
  9. {  
  10.     int i = b, j = e;  
  11.     while(i < j)  
  12.     {  
  13.         char tem = str[i];  
  14.         str[i] = str[j];  
  15.         str[j] = tem;  
  16.         i++;  
  17.         j--;  
  18.     }  
  19. }  
  20. void reverseWordsOfSentence(char *str)  
  21. {  
  22.     reverse(str, 0, strlen(str) - 1);  
  23.     for(int i = 0, len = strlen(str); i < len; )  
  24.     {  
  25.         int b = i;  
  26.         while(str[i++] != ' ' && str[i++] != '\0')  
  27.             ;  
  28.         reverse(str, b, i - 2);  
  29.     }  
  30. }  
  31.   
  32. int main()  
  33. {  
  34.     char str[] = "I come from shantou.";  
  35.     reverseWordsOfSentence(str);  
  36.     cout << str << endl;  
  37. }  

第10題

實現strstr()函數

  1. 不想做。  


第 11 題

求二叉樹中節點的最大距離 ...
如果我們把二叉樹看成一個圖,父子節點之間的連線看成是雙向的,
我們姑且定義 " 距離 " 爲兩節點之間邊的個數。
寫一個程序,
求一棵二叉樹中相距最遠的兩個節點之間的距離。

  1. //總結來自《微軟編程之美》:  
  2. //  對於遞歸問題的分析,筆者有一些小小的體會:   
  3. //1. 先弄清楚遞歸的順序。在遞歸的實現中,往往需要假設後續的調用已經完成,在此  
  4. //基礎之上,才實現遞歸的邏輯。在該題中,我們就是假設已經把後面的長度計算出  
  5. //來了,然後繼續考慮後面的邏輯;   
  6. //2. 分析清楚遞歸體的邏輯,然後寫出來。比如在上面的問題中,遞歸體的邏輯就是如  
  7. //何計算兩邊最長的距離;   
  8. //3. 考慮清楚遞歸退出的邊界條件。也就說,哪些地方應該寫return。   
  9. //注意到以上 3 點,在面對遞歸問題的時候,我們將總是有章可循。   
  10. #include<iostream>  
  11. using namespace std;  
  12. struct Node  
  13. {  
  14.     Node *left;  
  15.     Node *right;  
  16.     int nMaxLeft;  
  17.     int nMaxRight;  
  18.     //char chValue;  
  19. };  
  20.   
  21. int nMaxLen = 0;  
  22.   
  23. int maxNode(Node *tree)  
  24. {  
  25.     return tree->nMaxLeft > tree->nMaxRight ?  
  26.         tree->nMaxLeft : tree->nMaxRight;  
  27. }  
  28.   
  29. void find(Node *tree)  
  30. {  
  31.     if(tree->left)  
  32.     {  
  33.         find(tree->left);  
  34.     }else  
  35.     {  
  36.         tree->nMaxLeft = 0;  
  37.     }  
  38.     if(tree->right)  
  39.     {  
  40.         find(tree->right);  
  41.     }else  
  42.     {  
  43.         tree->nMaxRight = 0;  
  44.     }  
  45.     tree->nMaxLeft = maxNode(tree->left) + 1;  
  46.     tree->nMaxRight = maxNode(tree->right) + 1;  
  47.     nMaxLen = nMaxLen > tree->nMaxLeft + tree->nMaxRight ? nMaxLen : tree->nMaxLeft + tree->nMaxRight;  
  48.   
  49. }  


第 13 題:

題目:輸入一個單向鏈表,輸出該鏈表中倒數第 k 個結點。鏈表的倒數第 0 個結點爲鏈表的尾指針。

  1. 已經做過。  


第 14 題:
題目:輸入一個已經按升序排序過的數組和一個數字,
在數組中查找兩個數,使得它們的和正好是輸入的那個數字。
要求時間複雜度是 O(n) 。如果有多對數字的和等於輸入的數字,輸出任意一對即可。
例如輸入數組 1 、 2 、 4 、 7 、 11 、 15 和數字 15 。由於 4+11=15 ,因此輸出 4 和 11 。

  1. 已經做過。  


第 15 題:
題目:輸入一顆二元查找樹,將該樹轉換爲它的鏡像,
即在轉換後的二元查找樹中,左子樹的結點都大於右子樹的結點。
用遞歸和循環兩種方法完成樹的鏡像轉換。

例如輸入
8
/ \
6 10

/\ /\
5 7 9 11
輸出:
8
/ \
10 6
/\ /\
11 9 7 5


  1. //基本思想:假設根的左右兩棵子樹都已經鏡像轉換好了,則只需改變根的左右鏈的指向互換就可以了  
  2. #include <iostream>  
  3. using namespace std;  
  4.   
  5. struct node  
  6. {  
  7.     int value;  
  8.     node *left;  
  9.     node *right;  
  10. };  
  11.   
  12. void display(node *root)  
  13. {  
  14.     if(!root)  
  15.         return ;  
  16.     display(root->left);  
  17.     cout << root->value << " ";  
  18.     display(root->right);  
  19. }  
  20.   
  21. node * build_tree()  
  22. {  
  23.     int a;  
  24.     cin >> a;  
  25.     if(a == 0)  
  26.     {  
  27.         return NULL;  
  28.     }  
  29.     node *root = new node();  
  30.     root->value = a;  
  31.     root->left = build_tree();  
  32.     root->right = build_tree();  
  33.     return root;  
  34. }  
  35.   
  36. void treeImage(node *root)  
  37. {  
  38.     if(!root)  
  39.         return;  
  40.     treeImage(root->left);  
  41.     treeImage(root->right);  
  42.     node *tem = root->left;  
  43.     root->left = root->right;  
  44.     root->right = tem;  
  45. }  
  46.   
  47. int main()  
  48. {  
  49.     node *root = build_tree();  
  50.     treeImage(root);  
  51.     display(root);  
  52.     return 0;  
  53. }  

第 16 題:
題目(微軟):
輸入一顆二元樹,從上往下按層打印樹的每個結點,同一層中按照從左往右的順序打印。
例如輸入
7
8
/ \
6 10
/ \ / \
5 7 9 11

輸出 8 6 10 5 7 9 11 。


  1. //基本思想:BFS  
  2. #include <iostream>  
  3. #include <ctime>  
  4. #include <queue>  
  5. using namespace std;  
  6.   
  7. struct node  
  8. {  
  9.     int value;  
  10.     node *left;  
  11.     node *right;  
  12.   
  13. };  
  14.   
  15. node * build_tree()  
  16. {  
  17.     int a;  
  18.     cin >> a;  
  19.     if(a == 0)  
  20.     {  
  21.         return NULL;  
  22.     }  
  23.     node *root = new node();  
  24.     root->value = a;  
  25.     root->left = build_tree();  
  26.     root->right = build_tree();  
  27.     return root;  
  28. }  
  29. void print(node *root)  
  30. {  
  31.     queue<node *> toPrint;  
  32.     if(root)  
  33.     {  
  34.         toPrint.push(root);  
  35.         while(!toPrint.empty())  
  36.         {  
  37.             node *tem = toPrint.front();  
  38.             toPrint.pop();  
  39.             cout << tem->value <<  " ";  
  40.             if(tem->left)  
  41.             {  
  42.                 toPrint.push(tem->left);  
  43.             }  
  44.             if(tem->right)  
  45.             {  
  46.                 toPrint.push(tem->right);  
  47.             }  
  48.         }  
  49.     }  
  50. }  
  51.   
  52. int main()  
  53. {  
  54.     node *root = build_tree();  
  55.     print(root);  
  56.     return 0;  
  57. }  



第 17 題:
題目:在一個字符串中找到第一個只出現一次的字符。如輸入 abaccdeff ,則輸出 b 。

分析:這道題是 2006 年 google 的一道筆試題。

  1. //注:此題解法參與了July的解法  
  2. //基本思想:涉及到出現次數的可以考慮一下用hash表  
  3. #include <iostream>  
  4. using namespace std;  
  5.   
  6. char findFirstSingle(char *str)  
  7. {  
  8.     int a[255];  
  9.     memset(str,0,sizeof(a));  
  10.     char *p = str;  
  11.     while(*p != '\0')  
  12.     {  
  13.         a[*p]++;  
  14.         p++;  
  15.     }  
  16.     p = str;  
  17.     while(*p != '\0')  
  18.     {  
  19.         if(a[*p] == 1);  
  20.         return *p;  
  21.     }  
  22.     return '\0';  
  23. }  




第 18 題:
題目: n 個數字( 0,1, … ,n-1 )形成一個圓圈,從數字 0 開始,
每次從這個圓圈中刪除第 m 個數字(第一個爲當前數字本身,第二個爲當前數字的下一個數
字)。
當一個數字刪除後,從被刪除數字的下一個繼續刪除第 m 個數字。
求出在這個圓圈中剩下的最後一個數字。

  1. //基本思想:用循環表模擬  
  2. //網上有比較牛的算法,但有點難理解  
  3. #include <iostream>  
  4. #include <ctime>  
  5. #include <queue>  
  6. using namespace std;  
  7.   
  8. struct node  
  9. {  
  10.     int value;  
  11.     node *next;  
  12.   
  13. };  
  14.   
  15. node* theLastGuy(int n, int m)  
  16. {  
  17.     if(n == 0)  
  18.         return NULL;  
  19.     node *head = new node();  
  20.     head->value = 0;  
  21.     node *cur = head;  
  22.     for(int i= 1; i < n; i++)  
  23.     {  
  24.         cur->next = new node();  
  25.         cur = cur->next;  
  26.         cur->value = i;  
  27.     }  
  28.     cur->next = head;  
  29.     cur = head;  
  30.     int s;  
  31.     while(cur->next)  
  32.     {  
  33.         s = m - 1;  
  34.         while(s--)  
  35.         {  
  36.             cur = cur->next;  
  37.         }  
  38.         node *tem = cur->next;  
  39.         cur->next = cur->next->next;  
  40.         tem->next = NULL;  
  41.         delete tem;  
  42.   
  43.     }  
  44. }  
  45.   
  46. int main()  
  47. {  
  48.     cout << "input n and m" << endl;  
  49.     int n, m;  
  50.     cin >> n >> m;  
  51.     theLastGuy(n, m);  
  52.     return 0;  
  53. }  



第 20 題:
題目:輸入一個表示整數的字符串,把該字符串轉換成整數並輸出。
例如輸入字符串 "345" ,則輸出整數 345 。

  1. //基本思想:‘3’- '0' = 3  
  2. #include <iostream>  
  3. using namespace std;  
  4.   
  5. void convert(char *a)  
  6. {  
  7.     for(int i = 0; i < strlen(a); i++)  
  8.     {  
  9.         cout << a[i] - '0';  
  10.     }  
  11. }  
  12. int main()  
  13. {  
  14.     char *a = "345";  
  15.     convert(a);  
  16.     return 0;  
  17. }  

第 21 題
2010 年中興面試題
編程求解:
輸入兩個整數 n 和 m ,從數列 1 , 2 , 3.......n 中隨意取幾個數
使其和等於 m , 要求將其中所有的可能組合列出來 .

  1. //基本思想:組合數學,用母函數解即可。  
  2. //母函數:將離散的數列變成對應連續的冪數,冪指數爲對應的數列項的值  
  3. //母函數的G(x)=  (1+x+x^2+x^3+x^4+x^5+....)*(1+x^2+x^4+x^6+x^8+x^10+....)*  
  4.   
  5. (1+x^3+x^6+x^9+x^12....).....  
  6. //其中第一項表示的1表示第一個數列取一次,x表示取兩次,...其它的數列也一樣。  
  7. //實現時,用數組下標表示冪指數,對應的值表示該冪數的係數,然後對多項式展開就可以了。  
  8. //只要計算到下標爲m的數組值就可以了,注意循環變量每次的增量。  
  9. #include <iostream>  
  10. #include <ctime>  
  11. using namespace std;  
  12. const int N = 10000;  
  13. int c1[N], c2[N];  
  14. int combination(int n, int m)  
  15. {  
  16.     int len = 0;  
  17.     for(int i = 1; i <= n ; i++)  
  18.         len += i;  
  19.     if(m > len)  
  20.         return 0;  
  21.     for(int i = 0; i <= m; i ++)  
  22.     {  
  23.         c1[i] = c2[i] = 0;  
  24.     }  
  25.     for(int i = 0; i <= 1; i++)  
  26.     {  
  27.         c1[i] = 1;  
  28.     }  
  29.     for(int i = 1; i < n ; i++)  
  30.         for(int j = 0; j <= m; j++)  
  31.             for(int k = 0;k <= i + 1 && k + j <= m; k += i+1)  
  32.             {  
  33.                 c2[j + k] += c1[j];  
  34.             }  
  35.     for(int i = 0; i <= m; i++)  
  36.     {  
  37.         c1[i] = c2[i];  
  38.         c2[i] = 0;  
  39.     }  
  40.     return c1[m];  
  41. }  
  42. int main()  
  43. {  
  44.     int n , m;  
  45.     cin >> n >> m;  
  46.     cout << combination(n,m);  
  47. }  


第 25 題:
寫一個函數 , 它的原形是 int continumax(char *outputstr,char *intputstr)
功能:
在字符串中找出連續最長的數字串,並把這個串的長度返回,
並把這個最長數字串付給其中一個函數參數 outputstr 所指內存。
例如: "abcd12345ed125ss123456789" 的首地址傳給 intputstr 後,函數將返回 9 ,

outputstr 所指的值爲 123456789

  1. //基本思想:dp  
  2. #include <iostream>  
  3. #include <ctime>  
  4. using namespace std;  
  5. const int N = 10000;  
  6. int a[N];  
  7. int maxsub(char *str)  
  8. {  
  9.     if(!str)  
  10.         return 0;  
  11.     memset(a, 0, sizeof(a));  
  12.     if(str[0] >= '0' && str[0] <= '9')  
  13.         a[0] = 1;  
  14.     else  
  15.         a[0] = 0;  
  16.     int len = strlen(str);  
  17.     for(int i = 1; i < len; i++)  
  18.     {  
  19.         a[i] = str[i] >= 'a' && str[i] <= 'z' ? 0 : a[i - 1] + 1;  
  20.     }  
  21.     int max = 0;  
  22.     for(int i = 0; i < len; i++)  
  23.     {  
  24.         max = max > a[i] ? max : a[i];  
  25.     }  
  26.     return max;  
  27. }  
  28.   
  29. int main()  
  30. {  
  31.     char *str = "ab12ab1234a";  
  32.     cout << maxsub(str);  
  33. }   

26. 左旋轉字符串
題目:
定義字符串的左旋轉操作:把字符串前面的若干個字符移動到字符串的尾部。
如把字符串 abcdef 左旋轉 2 位得到字符串 cdefab 。請實現字符串左旋轉的函數。

要求時間對長度爲 n 的字符串操作的複雜度爲 O(n) ,輔助內存爲 O(1) 。

  1. //基本思想:ad-hoc  
  2. #include <iostream>  
  3. #include <ctime>  
  4. using namespace std;  
  5. const int N = 10000;  
  6.   
  7. void reverse(char *str, int b, int e)  
  8. {  
  9.     int i = b, j = e;  
  10.     while(i < j)  
  11.     {  
  12.         char tem = str[i];  
  13.         str[i] = str[j];  
  14.         str[j] = tem;  
  15.         i++;  
  16.         j--;  
  17.     }  
  18. }  
  19. void shift(char *str, int n)  
  20. {  
  21.     reverse(str, 0, strlen(str) - 1);  
  22.     reverse(str, 0, strlen(str) - 1 - n);  
  23.     reverse(str, strlen(str) - n, strlen(str) - 1);  
  24. }  
  25.   
  26. int main()  
  27. {  
  28.     char str[] = "abcde";  
  29.     shift(str, 2);  
  30.     cout << str << endl;  
  31. }  

27. 跳臺階問題
題目:一個臺階總共有 n 級,如果一次可以跳 1 級,也可以跳 2 級。
求總共有多少總跳法,並分析算法的時間複雜度。
這道題最近經常出現,包括 MicroStrategy 等比較重視算法的公司
都曾先後選用過個這道題作爲面試題或者筆試題。

  1. //基本思想:dp。  
  2. //設a[i]爲第i階的跳法總數。從第i-1階和第i-2階可以跳到第i階  
  3. //所以a[i] = a[i - 2] + a[i - 1];  
  4. #include <iostream>  
  5. #include <ctime>  
  6. using namespace std;  
  7. const int N = 10000;  
  8.   
  9. int jump(int n)  
  10. {  
  11.     int a[N];  
  12.     a[1] = 1;  
  13.     a[2] = 2;  
  14.     for(int i = 3; i <= n; i++)  
  15.     {  
  16.         a[i] = a[i - 2] + a[i - 1];  
  17.     }  
  18.     return a[n];  
  19. }  
  20.   
  21. int main()  
  22. {  
  23.     int n;  
  24.     while(cin >> n)  
  25.     {  
  26.         cout << jump(n) << endl;  
  27.     }  
  28.     return 0;  
  29. }  
28. 整數的二進制表示中 1 的個數
題目:輸入一個整數,求該整數的二進制表達中有多少個 1 。
例如輸入 10 ,由於其二進制表示爲 1010 ,有兩個 1 ,因此輸出 2 。
分析:
這是一道很基本的考查位運算的面試題。
包括微軟在內的很多公司都曾採用過這道題。
  1. //基本思想:xxxxxx10000 & (xxxxxx10000-1) = xxxxxx00000  
  2. //參考了july的方法。  
  3.   
  4. #include <iostream>  
  5. #include <ctime>  
  6. using namespace std;  
  7. const int N = 10000;  
  8.   
  9. int binary(int n)  
  10. {  
  11.     int count = 0;  
  12.     while(n)  
  13.     {  
  14.         n = n & (n - 1);  
  15.         count++;  
  16.     }  
  17.     return count;  
  18. }  
  19.   
  20. int main()  
  21. {  
  22.     cout << binary(10) << endl;  
  23. }  

29. 棧的 push 、 pop 序列
題目:輸入兩個整數序列。其中一個序列表示棧的 push 順序,
判斷另一個序列有沒有可能是對應的 pop 順序。
爲了簡單起見,我們假設 push 序列的任意兩個整數都是不相等的。
比如輸入的 push 序列是 1 、 2 、 3 、 4 、 5 ,那麼 4 、 5 、 3 、 2 、 1 就有可能是一個 pop 系列。
因爲可以有如下的 push 和 pop 序列:
push 1 , push 2 , push 3 , push 4 , pop , push 5 , pop , pop , pop , pop ,
這樣得到的 pop 序列就是 4 、 5 、 3 、 2 、 1 。
但序列 4 、 3 、 5 、 1 、 2 就不可能是 push 序列 1 、 2 、 3 、 4 、 5 的 pop 序列。

  1. //基本思想:ad-hoc  
  2. //模擬  
  3.   
  4. #include <iostream>  
  5. #include <ctime>  
  6. using namespace std;  
  7. const int N = 10000;  
  8.   
  9. int stack[N];  
  10. int top = -1;  
  11.   
  12. bool fun(int *push, int *pop, int n)  
  13. {  
  14.     int i = 0, j = 0;  
  15.     for(int i= 0; i < n; i++)  
  16.     {  
  17.         if(push[i] == pop[j])  
  18.             j++;  
  19.         else  
  20.             stack[++top] = push[i];  
  21.     }  
  22.     while(top >= 0)  
  23.     {  
  24.         if(stack[top--] != pop[j++])  
  25.             return false;  
  26.     }  
  27.     return true;  
  28. }  
  29. int main()  
  30. {  
  31.     int push[] = {1,2,3,4,5};  
  32.     int pop[] = {4,3,5,1,2};  
  33.     cout << fun(push, pop, 5);  
  34. }  







43. 遞歸和非遞歸倆種方法實現二叉樹的前序遍歷。

  1. //二叉樹的非遞歸深度遍歷  
  2. //基本思想:用棧,循環 模擬遞歸遍歷的操作  
  3. //如果存在左節點,則一直將左節點壓入棧,沒有才壓右節點  
  4. #include <iostream>  
  5. #include <stack>  
  6. using namespace std;  
  7.   
  8. struct node  
  9. {  
  10.     int value;  
  11.     node *left;  
  12.     node *right;  
  13. };  
  14.   
  15. node* build_tree()  
  16. {  
  17.     int a;  
  18.     cin >> a;  
  19.     if(a == 0)  
  20.     {  
  21.         return NULL;  
  22.     }  
  23.     node *root = new node();  
  24.     root->value = a;  
  25.     root->left = build_tree();  
  26.     root->right = build_tree();  
  27.     return root;  
  28. }   
  29. void traverse(node *root)  
  30. {  
  31.     stack<node *> backtrack;  
  32.     while(root || !backtrack.empty())  
  33.     {  
  34.         if(root)  
  35.         {  
  36.             cout << root->value;  
  37.             backtrack.push(root);  
  38.             root = root->left;  
  39.         }else  
  40.         {  
  41.             root = backtrack.top();  
  42.             backtrack.pop();  
  43.             root = root->right;  
  44.         }  
  45.     }  
  46. }  
  47. int main()  
  48. {  
  49.     node *root = build_tree();  
  50.     traverse(root);  
  51.     return 0;  
  52. }  

整數字符串轉化

  1. //整數字符串轉化  
  2.   
  3.   
  4. #include <iostream>  
  5. #include <ctime>  
  6. using namespace std;  
  7. const int N = 10000;  
  8.   
  9. void myItoa(int n)  
  10. {  
  11.     char str[N];  
  12.     int i = 0;  
  13.     while(n)  
  14.     {  
  15.         str[i++] = n % 10 + '0';  
  16.         n = n / 10;  
  17.     }  
  18.     int k = 0, j = i -1;  
  19.     while(k < j)  
  20.     {  
  21.         swap(str[k],str[j]);  
  22.         k++;  
  23.         j--;  
  24.     }  
  25.     str[i] = '\0';  
  26.     cout << str << endl;  
  27. }  
  28.   
  29. int main()  
  30. {  
  31.     myItoa(10);  
  32. }  

字符串整數轉化

  1. #include <iostream>  
  2. #include <ctime>  
  3. using namespace std;  
  4. const int N = 10000;  
  5.   
  6. void myAtoi(char *a)  
  7. {  
  8.     int sum = 0;  
  9.     int len = strlen(a);  
  10.     for(int i = len - 1, j = 1; i >= 0; i--,j *= 10)  
  11.     {  
  12.         sum += (a[i] - '0') * j;  
  13.     }  
  14.     cout << sum << endl;  
  15. }  
  16.   
  17. int main()  
  18. {  
  19.     myAtoi("1020");  
  20. }  

字符串拷貝函數

  1. #include <iostream>  
  2. #include <ctime>  
  3. #include <cassert>  
  4. using namespace std;  
  5. const int N = 10000;  
  6.   
  7. char *strcpy(char *dest, char *src)  
  8. {  
  9.     char *cp = dest;  
  10.     while( *cp++ = *src++)  
  11.         ;  
  12.     return dest;  
  13. }  
  14.   
  15. int main()  
  16. {  
  17.     char test[] = "123";  
  18.     char dest[100];  
  19.     cout << strcpy(dest, test);  
  20.   
  21. }  

字符串循環右移n位

  1. //先整體反轉,再局部反轉  
  2.   
  3. #include <iostream>  
  4. #include <ctime>  
  5. #include <cassert>  
  6. using namespace std;  
  7. const int N = 10000;  
  8. void rev(char *p, int b, int e)  
  9. {  
  10.     while(b < e)  
  11.     {  
  12.         swap(p[b++],p[e--]);  
  13.     }  
  14. }  
  15.   
  16. void shift(char *p, int n)  
  17. {  
  18.     rev(p, 0, strlen(p) - 1);  
  19.     rev(p, 0, n - 1);  
  20.     rev(p, n,  strlen(p) - 1);  
  21. }  
  22.   
  23. int main()  
  24. {  
  25.     char a[] = "abcdefghi";  
  26.     shift(a,2);  
  27.     cout << a << endl;  
  28.   
  29. }  


最長公共子序列

  1. //dp  
  2. c[i, j] =            0         i == 0 或 j == 0  
  3.   
  4. c[i, j] =            c[ i - 1, j - 1] + 1           i, j >0 && xi == yj  
  5.   
  6. c[i, j] =            max( c[ i - 1, j ], c[ i, j - 1 ] )                i, j>0 && i != j  




輸入一字符串,找出其中出現的相同且長度最長的字符串

  1. //轉自網上,用了O(n^3)的方法  
  2. //ps:正規解法應該用字典樹  
  3. #include "iostream"  
  4. #include "string"  
  5. using namespace std;  
  6.    
  7.    
  8. int main()   
  9. {  
  10.     string strInput;  
  11.     cout << "Input a string: " << endl;  
  12.     cin >> strInput;  
  13.     string strTemp;  
  14.     for (size_t i = strInput.length() - 1; i > 1; i--)  
  15.     {  
  16.         for (size_t j = 0; j < strInput.length(); j++)  
  17.         {  
  18.             if ((i + j) <= strInput.length())  
  19.             {  
  20.                 size_t szForw = 0;  
  21.                 size_t szBacw = 0;  
  22.                 strTemp = strInput.substr(j, i);  
  23.                 szForw = strInput.find(strTemp);  
  24.                 szBacw = strInput.rfind(strTemp);  
  25.                 if (szBacw != szForw)  
  26.                 {  
  27.                     cout << strTemp << " " << szForw + 1 << endl;  
  28.                     return 0;  
  29.                 }  
  30.             }  
  31.         }  
  32.     }  
  33.    
  34.     return 1;  
  35. }  



校門外的樹

某校大門外長度爲L的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1。我們可以把馬路看成一個數軸,馬路的一端在數軸0的位置,另一端在L的位置;數軸上的每個整數點,即012,……,L,都種有一棵樹。

由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止點的座標都是整數,區域之間可能有重合的部分。現在要把這些區域中的樹(包括區域端點處的兩棵樹)移走。你的任務是計算將這些樹都移走後,馬路上還有多少棵樹。

  1. //基本思想:位圖法  
  2.   
  3. #include <iostream>  
  4. #include <bitset>  
  5. using namespace std;  
  6.   
  7. const int N = 10000;  
  8. struct Segment  
  9. {  
  10.     int start;  
  11.     int end;  
  12. };  
  13.   
  14. int coverage(Segment *segments, int n)  
  15. {  
  16.     bool c[N];  
  17.     memset(c, 0, sizeof(c));  
  18.     int end = 0;  
  19.     for(int i = 0; i < n; i++)  
  20.     {  
  21.         for(int j = segments[i].start; j < segments[i].end; j++)  
  22.         {  
  23.             c[j] = true;  
  24.         }  
  25.         if(segments[i].end > end)  
  26.             end = segments[i].end;  
  27.     }  
  28.     int max = 0;  
  29.     for(int i= 0; i < end; i++)  
  30.     {  
  31.         int count = 1;  
  32.         if(c[i] == true)  
  33.         {  
  34.             while(c[++i] == true)  
  35.             {  
  36.                 count++;  
  37.             }  
  38.         }  
  39.         if(count > max)  
  40.             max= count;  
  41.     }  
  42.     return max;  
  43. };  
  44.   
  45. int main()  
  46. {  
  47.     Segment s1;  
  48.     s1.start = 0;  
  49.     s1.end = 5;  
  50.     Segment s2;  
  51.     s2.start = 6;  
  52.     s2.end = 7;  
  53.     Segment ss[] = {s1,s2};  
  54.     cout << coverage(ss, 2);  
  55. }  


Suppose there  is a two-dimension array  a[1 .. 60,1 .. 70] with 60 rows and 70 
columns ,whose main order is the column order(以列序爲主序). If the base address is 10000 
and each element occupies two storage unit, then the storage address of a[32,58] is ( ). (無第
0 行第 0 列元素) 
A)14454      B)16904      C)16902      D) None of above 


Sorting the  sequence (25,84,21,47,15,27,68,35,20) , the sequence changes  are 
(20,15,21,25,47,27,68,35,84),(15,20,21,25,35,27,47,68,84),(15,20,21,25,27,35,47,68,84). 
Which kind of sorting algorithm we used ? ( ) 
 A) Selection sort    B) shell sort    C) merge sort    D) quick sort 


怎樣編寫一個程序,把一個有序整數數組放到二叉樹中?

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. struct Node  
  5. {  
  6.     int value;  
  7.     Node *left;  
  8.     Node *right;  
  9. };  
  10. void binaryTree(Node *&root, int a[], int n)  
  11. {  
  12.     if(n > 0)  
  13.     {  
  14.         root = new Node();   
  15.         root->value = a[n/2];  
  16.         binaryTree(root->left , a,  n/2 );  
  17.         binaryTree(root->right, a + n/2 + 1, n - n/2 - 1);  
  18.     }else  
  19.     {  
  20.         root = NULL;  
  21.     }  
  22. }  
  23. void display(Node *root)  
  24. {  
  25.     if(!root)  
  26.         return ;  
  27.     display(root->left);  
  28.     cout << root->value << " ";  
  29.     display(root->right);  
  30. }  
  31. int main()  
  32. {  
  33.     int a[] = {1,2,3,4,5};  
  34.     Node *root = NULL;  
  35.     binaryTree(root, a, 5);  
  36.     display(root);  
  37. }  

給出一個函數來輸出一個字符串的所有排列。

  1. //基本思想:遞歸  
  2. //從要全排列的字符串中取出一個字符,加入到prefix字符串中  
  3. //然後遞歸  
  4. //當要全排列的字符串爲空時,就可以輸出prefix字符串了。  
  5. #include <iostream>  
  6. #include <string>  
  7. using namespace std;  
  8.    
  9. void permut(string pre, string toPermut)  
  10. {  
  11.     if(toPermut.length() == 0)  
  12.         cout << pre << endl;  
  13.     else  
  14.     {  
  15.         for(int i = 0; i < toPermut.length(); i++)  
  16.         {  
  17.             permut(pre + toPermut[i], toPermut.substr(0,i)+toPermut.substr(i+1,toPermut.length()));  
  18.         }  
  19.     }  
  20. }  
  21. void print(string str)  
  22. {  
  23.     permut("",str);  
  24. }  
  25.    
  26. int main(void)  
  27. {  
  28.     print("abc");  
  29.     return 0;  
  30. }  

在鏈表裏如何發現循環鏈接?


  1. //基本思想:快慢指針  
  2. #include <iostream>  
  3. #include <string>  
  4. using namespace std;  
  5.   
  6. struct Node  
  7. {  
  8.     int value;  
  9.     Node *next;  
  10. };  
  11. bool hasCircle(Node *head)  
  12. {  
  13.     Node *fast;  
  14.     Node *slow;  
  15.     fast = slow = head;  
  16.     if(head == NULL  || head->next == NULL)  
  17.         return false;  
  18.     do  
  19.     {  
  20.         fast = fast->next;  
  21.         fast = fast->next;  
  22.         slow = slow->next;  
  23.     }while(fast != NULL && fast != slow);  
  24.     return !(fast == NULL);  
  25. }  
  26.    
  27. int main(void)  
  28. {  
  29.     Node *head = new Node();  
  30.     head->value = 1;  
  31.     Node *tem = head->next = new Node();  
  32.     tem->value = 2;  
  33.     tem->next = head;  
  34.     cout << hasCircle(head);  
  35.     return 0;  
  36. }  

給出一個單鏈表,不知道結點N的值,怎樣只遍歷一次就可以求出中間結點,寫出算法。

  1. //基本思路:快慢指針。  
  2. #include <iostream>  
  3. #include <ctime>  
  4. using namespace std;  
  5. struct Node  
  6. {  
  7.     int value;  
  8.     Node *next;  
  9. };  
  10. int middle(Node *head)  
  11. {  
  12.     Node *slow, *fast;  
  13.     slow = fast = head;  
  14.     while(fast && fast->next)  
  15.     {  
  16.         fast = fast->next->next;  
  17.         slow = slow->next;  
  18.     }  
  19.     return slow->value;  
  20. }  

尋找最大的k個數

  1. //基本思路:部分快速排序  
  2. #include <iostream>  
  3. using namespace std;  
  4.   
  5. int partition(int *a, int b, int e)  
  6. {  
  7.     int j = b - 1 ;  
  8.     for(int i = b; i < e - 1; i++)  
  9.     {  
  10.         if(a[i] < a[e-1])  
  11.         {  
  12.             j++;  
  13.         }else  
  14.         {  
  15.             int tem = a[++j];  
  16.             a[j] = a[i];  
  17.             a[i] = tem;  
  18.         }  
  19.     }  
  20.     int tem = a[++j];  
  21.     a[j] = a[e - 1];  
  22.     a[e - 1] = tem;  
  23.     return j;  
  24. }  
  25. void find(int *a, int s, int k)  
  26. {  
  27.     int p = partition(a, 0, s);  
  28.     int c = s - p;  
  29.     if(c == k)  
  30.     {  
  31.         for(int i = p; i < s; i++)  
  32.         {  
  33.             cout << a[i] << " ";  
  34.         }  
  35.     }else if(c < k)  
  36.     {  
  37.         for(int i = p; i < s; i++)  
  38.         {  
  39.             cout << a[i] << " ";  
  40.         }  
  41.         find(a, p, k - c);  
  42.     }else if(c > k)  
  43.     {  
  44.         find(a+p, s - p, k);  
  45.     }  
  46. }  
  47. int main()  
  48. {  
  49.     int a[] = {1,2,3};  
  50.     find(a, 3, 2);  
  51. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章