最近兩天連續面了四次,公司就不說了。覺得對我來說心態還是很重要的因素。
還是說題目吧:
1.1 求連通圖個數題目:
一個二維數組(M*N),每一個元素可以是任意26個小寫字母。如果數組中一個字母和周圍(上下左右)任意一個字母相同,則將這些字母一起看做一個“塊”。給定一個二維數組,求包含塊的多少。
思路:
有點求最小連通圖的味道。申請一個M*N的數組status用於記錄元素處理的狀態:沒有處理過的就為0,處理過的就為1。依次掃描數組中每一個元素,對於每一個元素,將周圍(上下左右)和其相等的元素的狀態置為1,並且遞迴處理這些元素。
代碼:
#include</usr/include/stdio.h>#define MAX_M 1000#define MAX_N 1000int status[MAX_M][MAX_N];void setNeighber(char *a, int m,int n,int m_size, int n_size);int func(char *a, int m,int n){ int i,j; int result=0; if(m<=0 || n<=0 || m>MAX_M || n>MAX_N || a==NULL) return -1; for(i=0;i<m;i++) for(j=0;j<n;j++) { if(status[i][j]==0) { result++; setNeighber(a,i,j,m,n); } } return result;}void setNeighber(char *a, int m,int n,int m_size,int n_size){ status[m][n]=1; if(m>0 && status[m-1][n]==0 && a[m*n_size+n]==a[(m-1)*n_size+n]) setNeighber(a,m-1,n,m_size,n_size); if(m<m_size-1 && status[m+1][n]==0 && a[m*n_size+n]==a[(m+1)*n_size+n]) setNeighber(a,m+1,n,m_size,n_size); if(n>0 && status[m][n-1]==0 && a[m*n_size+n]==a[m*n_size+n-1]) setNeighber(a,m,n-1,m_size,n_size); if(n<n_size-1 && status[m][n+1]==0 && a[m*n_size+n]==a[m*n_size+n+1]) setNeighber(a,m,n+1,m_size,n_size);}int main(int argc,char * argv[]){ char a[4][4]={ 'a','c','d','d', 'a','a','c','d', 'b','b','b','d', 'e','a','d','d', };//此用例輸出7 printf("%d",func(a,4,4)); return 0;}
1.2 二叉尋找樹問題題目:
給定一個二叉尋找樹和一個元素(假設key為int):如果這個元素在樹中則返回所在的結點;不在該樹中則返回小於該元素的最大數所在的結點。
思路:
考察二叉尋找樹的性質:(左孩子<=根結點<=右孩子)。根據這個性質進行二分尋找,會出現兩種情況:
- 找到該元素,返回其所在結點。
- 找不到元素,必定到達某個葉子結點某個孩子結點(為NULL指標),又分兩種情況:
- 找到某個葉子結點的右孩子,返回這個葉子結點
- 找到某個葉子結點的左孩子,返回尋找路徑中的最後一個小於該元素的結點(即最後一個向右拐的結點)。
代碼:
#include<stdio.h>#include<stdlib.h>typedef struct Node{struct Node* left;struct Node* right;int element;} *TreeNode;TreeNode find(TreeNode root,int m){TreeNode TmpNode = root;TreeNode result = NULL;while(TmpNode != NULL){if(TmpNode->element == m){printf("Found!The node <= %d is %d.\n",m,TmpNode->element);return TmpNode;}else if(TmpNode->element > m)TmpNode = TmpNode->left;else{result = TmpNode;TmpNode = TmpNode->right;}}if(result== NULL)printf("Not found!\n");elseprintf("Found!The node <= %d is %d.\n",m,result->element);return result;}int main(int argc,char* argv[]){TreeNode root = (TreeNode)malloc(sizeof(struct Node));TreeNode node01 = (TreeNode)malloc(sizeof(struct Node));TreeNode node02 = (TreeNode)malloc(sizeof(struct Node));TreeNode node21 = (TreeNode)malloc(sizeof(struct Node));TreeNode pResult = NULL;root->element = 20;node01->element = 10;node02->element = 30;node21->element = 25;root->left = node01;root->right = node02;node01->left = NULL;node01->right = NULL;node02->left = node21;node02->right = NULL;node21->left = NULL;node21->right = NULL;pResult=find(root,10);pResult=find(root,20);pResult=find(root,25);pResult=find(root,30);pResult=find(root,15);pResult=find(root,22);pResult=find(root,28);pResult=find(root,40);return 0;}
output
:! gcc -Wall -O ms2.c -o ms2:!./ms2Found!The node <= 10 is 10.Found!The node <= 20 is 20.Found!The node <= 25 is 25.Found!The node <= 30 is 30.Found!The node <= 15 is 10.Found!The node <= 22 is 20.Found!The node <= 28 is 25.Found!The node <= 40 is 30.
1.3.1海量資料處理的一個問題答案無非就是:hash劃分成記憶體可以放下的小檔案;在對應的小檔案中求解。1.3.2帶有random指標的單向鏈表的複製問題題目:一個特殊的單鏈表,除了帶有一個element元素(不妨設為int),和指向下一個結點的next指標外,還帶有個一個特殊的random指標:該指標隨機的指向該鏈表中的任意一個元素。給定一個這樣的鏈表,“複製”一個。思路:直接複製肯定不行,因為新舊鏈表中的random指標的值(即新舊結點中結點的地址)發生了變化。解法1:一個簡單的方法為:先掃描一遍原鏈表,複製element和next指標。再掃描一個原鏈表,對每個結點的random指標,判斷其所指向的結點在原鏈表中的位置,即從頭開始next幾次和random相等(注意:必鬚根據next和random相等來判斷是否是這個結點,而不應該根據)。將目標鏈表中的對應結點的地址賦給對應結點的random指標。時間複雜度為O(n^2)。解法2:其實非常非常非常簡單!我們要的只是新舊鏈表的一個對應關係,so,只要用一個(舊鏈表結點地址->新鏈表結點地址)的map就行了!僅掃描兩遍(第一遍建立新鏈表,並建立map,第二遍只需根據map給新鏈表的結點賦值就行了)就可以了。當時只想起這個方法,感覺肯定存線上性演算法,但死活想不出來了,然後還沒走回宿舍就想起來了……2.1.經典的快排代碼注意:可以最佳化的地方有兩個:
- 取劃分元素的時候不是隨機取,而是隨機取三個,用中間那個來劃分,這樣可以一定程提高效率。
- 當元素數小於某個閾值的時候,可以用插入、冒泡、選擇等簡單排序方法,而不是繼續遞迴。
代碼:2.2.上台階的方法問題題目:N階台階,一次可以上1層或2層,問有多少種上台階的方法。思路:遞推:
解法1:假設用f(n)表示上n階台階的方法。則上完n-1階只需在上一層就可以;上完n-2階只需上2層就可以了。所以f(n)=f(n-1)+f(n-2)(其實就是那個斐波那契數列)。可能有人覺得上完n-2階後,剩下兩階有兩種方法,但是上兩個1階的方法已經在前一項f(n-1)中包含了,再算上的話就重複了。可能解法2的思路更清晰。
解法2:不是從最後考慮,而是從第一步考慮:第一步上1階,剩下有f(n-1)種方法;第一步上2階,剩下有f(n-2)種方法。所以f(n)=f(n-1)+f(n-2)。3. 8/18/20123.13.1.1 求多精度浮點數x的n次冪。
3.1.2 序列化和發序列化二叉樹http://blog.csdn.net/ssjhust123/article/details/77776653.2 3.2.1 股票一年中每天的價格曲線,只能買入賣出一次,求最大收益。假設買入數量一定。
3.2.2 the k-th biggest
3.3 將一個字串轉化為ASCII碼。