几道面试题
/** wenbin Reverse the list **/ /* 逆转单链表,没什么技巧,用3个指针即可 */ #include <cstdio> #define LL __int64 using namespace std; /* .................................................................................................................................. */ const int M = 100100; const int INF = 2139062143; const int mod = 1000000007; int __ = 0; #define BIAOJI printf("yes%d\n",++__); class node { public: int val; node* next; }; void PRINTLIST(node *root) { while(root) { printf("%d ",root->val); root = root->next; } printf("\n"); } node *Reverse(node *root) { if( root == NULL )return NULL; if( root->next== NULL )return root; node *p1,*p2,*p3; p1 = root; p2 = p1->next; p3 = p2->next; p1->next = NULL; while( p2 ) { p3 = p2->next; p2->next = p1; p1 = p2; p2 = p3; } return p1; } int main() { int a[6] = {4,5,6,7,8,9}; int n = 6; node *root = new node(); node *p = root; p->val = a[0]; p->next = NULL; for(int i = 1; i < n; ++i) { p->next = new node(); p = p->next; p->val = a[i]; p->next = NULL; } printf("initial list is :\n"); PRINTLIST(root); printf("\nresverse list is :\n"); PRINTLIST(Reverse(root)); return 0; }
/** wenbin **/ /* 在m*n的矩阵中找M存在不 从左下角开始找,这样就有判断的方向了。。。面试过说了后才恍然大悟。。。这种技巧题真是。。。 回来要想想的是这种算法的正确性,一开始会怀疑这种算法正确性,但是模拟一下后发现还真是对的。。。 */ #include <cstdio> #define LL __int64 using namespace std; /* .................................................................................................................................. */ const int M = 100100; const int INF = 2139062143; const int mod = 1000000007; int __ = 0; #define BIAOJI printf("yes%d\n",++__); int main() { int m = 5; int n = 3; int M = 8; int a[5][3] = {{1 , 2 , 3 }, {4 , 5 , 6 }, {7 , 8 , 9 }, {10, 11, 12}, {13, 14, 15} }; printf("the matrix a is:\n"); for( int i = 0; i < m; ++i ) { for( int j = 0; j < n; ++j ) printf("%-3d",a[i][j]); printf("\n"); } printf("\nthe M is:%3d\n",M); int i = m-1,j = 0; while( i >= 0 && j < n ) { if( a[i][j] == M ) { printf("\nfind M! location is a[%d][%d]%3d\n",i,j,M); break; } else if( M < a[i][j] )i--; else j++; } if( i < 0 || j >=n )printf("\nnot find the M %d\n",M); return 0; }
/** wenbin **/ /* 已知a[i] b[i] = a[0]*..*a[i-1]*a[i+1]*..*a[n-1] 不能用除法,求b[i] 这种脑经急转弯的题还真不会。。。我还是百度了才知道这个技巧。。。 */ #include <cstdio> #define LL __int64 using namespace std; /* .................................................................................................................................. */ const int M = 100100; const int INF = 2139062143; const int mod = 1000000007; int __ = 0; #define BIAOJI printf("yes%d\n",++__); int main() { int a[10] = {1,2,3,4,5,6,7,8,9}; int b[10] = {0}; int n = 9; printf("array a is :\n"); for( int i = 0; i < n; ++i )printf("%d ",a[i]); printf("\n"); b[0]=1; for( int i = 1; i < n; ++i )//b[n-1] will ok b[i]=b[i-1]*a[i-1]; b[0]=1; for( int i = n-1; i > 0; --i )//b[0] will ok { b[i]=b[i]*b[0]; b[0]*=a[i]; } printf("\narray b is :\n"); for( int i = 0; i < n; ++i )printf("%d ",b[i]); printf("\n"); return 0; }
/** wenbin **/ #include <cstdio> #define LL __int64 using namespace std; /* .................................................................................................................................. */ const int M = 100100; const int INF = 2139062143; const int mod = 1000000007; int __ = 0; #define BIAOJI printf("yes%d\n",++__); /* 最大连续子串和 经典dp吧 定义b[i]为包含a[i]的最大连续子串和 即b[i] = max(b[i-1]+a[i],a[i]); 那sum = max(b[i]); 由于求sum是遍历b[i]一遍,故可以将b[]优化为b降低空间复杂度 时间复杂度O(n) 空间复杂度O(1) */ int SUM1(int *a, int n) { int sum = 0 - INF; int b = 0; for( int i = 0; i < n; ++i) { if( b > 0 ) b += a[i]; else b = a[i]; if( sum < b ) sum = b; } return sum; } /* 这个dp以前没遇到过,但是貌似和连续的有类似的感觉。试着优化吧 最大非连续子串和 定义b[i]为包含a[i]的最大非连续子串和 即b[i] = max( b[j]+a[i], a[i] ) 0<=j<i-1 时间复杂度O(n^2) 空间复杂度O(n) */ int SUM2(int *a,int n) { int sum = 0 - INF; int b[20] = {0}; for( int i = 0; i < n; ++i) { int k = 0 - INF; for(int j = 0; j < i-1; ++j) { if( k < b[j] ) k = b[j]; } if( i-2 >= 0 && k > 0) b[i] = k + a[i]; else b[i] = a[i]; if( sum < b[i] ) sum = b[i]; } return sum; } /* 最大非连续子串和 优化一 去掉内存循环 定义b[i]为包含a[i]的最大非连续子串和 即b[i] = max( b[j]+a[i], a[i] ) 0<=j<i-1 时间复杂度O(n) 空间复杂度O(n) */ int SUM3(int *a,int n) { int sum = 0 - INF; int b[20] = {0}; int k = 0 - INF; for( int i = 0; i < n; ++i) { if( i-2 >= 0 && k < b[i-2] )k = b[i-2]; if( i-2 >= 0 && k > 0) b[i] = k + a[i]; else b[i] = a[i]; if( sum < b[i] ) sum = b[i]; } return sum; } /* 最大非连续子串和 优化二 去掉内存循环,使用b[3]的循环数组优化空间 定义b[i]为包含a[i]的最大非连续子串和 即b[i] = max( b[j]+a[i], a[i] ) 0<=j<i-1 时间复杂度O(n) 空间复杂度O(1) */ int SUM4(int *a,int n) { int sum = 0 - INF; int b[3] = {0}; int k = 0 - INF; for( int i = 0; i < n; ++i) { if( i-2 >= 0 && k < b[(i-2+3)%3] )k = b[(i-2+3)%3]; if( i-2 >= 0 && k > 0) b[i%3] = k + a[i]; else b[i%3] = a[i]; if( sum < b[i%3] ) sum = b[i%3]; } return sum; } int main() { int a[13] = {1,-2,3,-4,5,-3,7,8,-9,11,-6,7,12}; int n = 13; printf("最大连续子串和为: %d\n\n",SUM1(a,n)); printf("最大非连续子串和为: %d\n\n",SUM2(a,n)); printf("优化一 最大非连续子串和为: %d\n\n",SUM3(a,n)); printf("优化二 最大非连续子串和为: %d\n\n",SUM4(a,n)); return 0; }
收获不会与付出成反比
by juandx