几道经典笔试题目
来源:互联网 发布:人工智能瓶颈阶段 编辑:程序博客网 时间:2024/04/28 19:38
1.递归合并有序链表
2.寻找二叉树中两个节点的最近的公共祖先
3.进制算法转换
4.大小写转换
5.求两同长数组的中位数问题
6.求数组的第k大的数字
7. 最接近S的中位数的k个数
1.递归合并有序链表
Node* mergAction(Node* head1,Node *head2){ Node *p=NULL; if(head1==NULL&&head2==NULL) return p; else if(head1==NULL) return head2; else if(head2==NULL) return head1; else { if(head1->data < head2->data) { p = head1; p->next = mergAction(head1->next,head2); } else { p = head2; p->next = mergAction(head1,head2->next); } return p; }}
2.寻找二叉树中两个节点的最近的公共祖先
class Node{ Node * left; Node * right; Node * parent;};/*查找p,q的最近公共祖先并将其返回。*/Node * NearestCommonAncestor(Node * p,Node * q);
Node * NearestCommonAncestor(Node * root,Node * p,Node * q){Node * temp; while(p!=NULL){p=p->parent;temp=q;while(temp!=NULL){if(p==temp->parent)return p;temp=temp->parent;}}}
解法2:算法思想:如果一个节点的左子树包含p,q中的一个节点,右子树包含另一个,则这个节点就是p,q的最近公共祖先。
/*查找a,b的最近公共祖先,root为根节点,out为最近公共祖先的指针地址*/int FindNCA(Node* root, Node* a, Node* b, Node** out) { if( root == null ) { return 0; }if( root == a || root == b ){ return 1;}int iLeft = FindNCA(root->left, a, b, out);if( iLeft == 2 ){ return 2;}int iRight = FindNCA(root->right, a, b, out);if( iRight == 2 ){ return 2;}if( iLeft + iRight == 2 ){ *out = root;}return iLeft + iRight;}void main() { Node* root = ...; Node* a = ...; Node* b = ...; Node* out = null; int i = FindNCA(root, a, b, &out); if( i == 2 ) { printf("Result pointer is %p", out); } else { printf("Not find pointer"); } }
3.进制算法转换
编程实现将十进制的整数转化成任意进制的整数,用户输入
一个十进制数R和想要转化的进制数X,程序输出转换后的X进制的整数。
算法思想:将十进制数R与进制X取模,即R%X的值作为X进制整数的倒数第一位,
然后使R等于R/X,再取R%X的值作为X进制整数的倒数第二位......依次类推,直
到最后R/X=0为止。
#include <iostream>#include <string>using namespace std;
/*将一个整型数字转化成字符型数字,例如 8->'8',12->'c'*/void numToChar(char &num){
/*num是0到9之间的数字*/ if(num<=9&&num>=0) { num+=48; }
/*num是10到15之间的数字*/ else { switch(num) { case 10:num='A'; case 11:num='B'; case 12:num='C'; case 13:num='D'; case 14:num='E'; case 15:num='F'; } }}
/*进制转化函数——r表示需要被转化的十进制数,x表示进制(1<x<17)*/void decimalTransmit(int r,int x){ string result;//保存x进制数 char temp; while(r>0) { temp=r%x; numToChar(temp); result+=temp; r=r/x; } /*输出转化后的x进制整数*/ for(int i=result.size()-1;i>=0;i--) cout<<result[i]; cout<<endl;}
int main(){ int R,X; cout<<"请输入一个十进制数和要转化的进制(用空格作为间隔符):"; cin>>R>>X; decimalTransmit(R,X); return 0;}
还有一个mton的算法,很漂亮,但是遗憾的是只支持1~10进制的转换。
void m2n(int m, char* mNum, int n, char* nNum) {int i = 0;char c, *p = nNum;//这是一个考察地方,是否能用最少乘法次数。while (*mNum != '\0')i = i*m + *mNum++ - '0';//辗转取余while (i) {*p++ = i % n + '0';i /= n;}*p-- = '\0';//逆置余数序列while (p > nNum) {c = *p;*p-- = *nNum;*nNum++ = c;}}
4.大小写转换
#define to_uppercase(ch) ((ch) - 'a' + 'A')#define to_lowercase(ch) ((ch) - 'A' + 'a')
以后记不住,记住带入特殊值作检验:
‘a’->‘A’ ‘a’ - ‘a’ + ‘A’
‘A’->‘a’ ‘A’ - 'A' + 'a'
貌似这么简答我都在考场上想了很久,足见状态之差
5.求两同长数组的中位数问题
中位数问题:设X[0:n-1]和Y[0:n-1]为两个数组,每个数组中含有N个 已经排好序的数。试设计一个O(logn)时间算法,找出X和Y的2N个数的中位数。
第一行: n,为x和y数组的元素个数
第二行: x数组的n个数,用空格分隔
第三行: y数组的n个数,用空格分隔
#include <stdio.h>#include <stdlib.h>int main(){ //两个数组 int len = 0; //获取数组的长度 scanf("%d", &len); //动态分配数组 int * a; int * b; a = (int *)malloc(sizeof(int) * len); b = (int *)malloc(sizeof(int) * len); //获取每个数组的元素 for(int i=0; i < len; i++) { scanf("%d", &a[i]); } for(int j=0; j < len; j++) { scanf("%d", &b[j]); } //两个数组的左右端点的坐标 int aLeft = 0; int aRight = len - 1; int bLeft = 0; int bRight = len - 1; //两数组中间坐标 int aMid = 0; int bMid = 0; //迭代循环 while(true) { //printf("a left is %d right is %d, and b left is %d right is %d.\n", aLeft, aRight, bLeft, bRight); // 如果两个数组都只剩下两个元素,则中位数一定在其中 if( (aRight - aLeft) == 1 && (bRight - bLeft) == 1) { // 输出第一行的最大一个值 printf("%d ", (a[aLeft]>=b[bLeft])?a[aLeft]:b[bLeft]); // 输出第一行的最小一个值 printf("%d\n", (a[aRight]<=b[bRight])?a[aRight]:b[bRight]); // 结束循环 break; } else { // 求解各个数组的中值 aMid = (int)((aLeft + aRight)/2); bMid = (int)((bLeft + bRight)/2); // 如果A中值小于B中值 if(a[aMid] < b[bMid]) { // 如果B中现存的数列是偶数个,右边值加一 if((bLeft + bRight + 1) % 2 == 0) { aLeft = aMid; bRight = bMid + 1; } else { aLeft = aMid; bRight = bMid; } } // 如果B中值小于A中值 else { // 如果A中现存的数列是偶数个,右边值加一 if((aLeft + aRight + 1) % 2 == 0) { aRight = aMid + 1; bLeft = bMid; } else { aRight = aMid; bLeft = bMid; } } } } return 0;}
6.求数组的第k大的数字:
太经典了,经常面试问到。具体参考《算法导论》
#include <cstdlib>#include <iostream>/** *求一个数组中的第k大数 *基本思想: *以最后一个元素x为轴,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况: *1.Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数; *2.Sa中元素的个数大于等于k,则返回Sa中的第k大数。 *时间复杂度近似为O(n) */using namespace std;void exchange(int &a,int &b){ int temp; temp=a; a=b; b=temp;}//快排的partition函数 int partition(int *a,int l,int r){ int i=l-1,j=l; int x=a[r]; int temp; for(j=l;j<r;j++) { if(a[j]>=x) //把比x大的数往前放 { exchange(a[j],a[i+1]); i++; } } exchange(a[r],a[i+1]); return i+1; }int k_element(int *a,int l,int r, int k){ if(l>=r) return a[l]; int q=partition(a,l,r); if(q==k-1) return a[q]; else if(q>=k) return k_element(a,l,q-1,k); //Sa中元素个数大于等于k else return k_element(a,q+1,r,k-(q+1)); //Sa中元素个数小于k }int main(int argc, char *argv[]){ int a[100]; int length; cin>>length; for(int i=0;i<length;i++) cin>>a[i]; cout<<k_element(a,0,length-1,4)<<endl; system("PAUSE"); return EXIT_SUCCESS;}
7. 最接近S的中位数的k个数
给定由n个互补相同的数组成的集合S以及正整数k<=n,试设计一个O(n)时间算法找出S中最接近S的中位数的k个数。
算法分析:
首先,通过select算法得到这个数组的中位数,然后最这个集合中的每一个数都减去这个中位数然后取abs();最后在第二步得到的集合中,取第k小的数,再取小于第k小的数的k-1个数,他们原来的数,就是要求的k个数。PS:此算法有缺陷,要求保证绝对值数组中无重复,否则无法线性。
- 几道经典笔试题目
- 几道经典的SQL笔试题目
- 几道经典的SQL笔试题目
- 几道经典的SQL笔试题目
- 几道经典的SQL笔试题目(有答案)
- 几道经典的SQL笔试题目(有答案)
- 几道经典的SQL笔试题目(有答案)
- SPFA几道经典题目
- 几道经典C 语言笔试题
- 几道经典SQL笔试题
- 几道经典的sql题目
- 几道经典的Mysql题目
- 关于位运算几道经典题目
- 几道经典的嵌入式C语言笔试题
- 几道经典的嵌入式C语言笔试题
- 几道经典的嵌入式C语言笔试题
- 几道经典的嵌入式C语言笔试题
- 几道经典的嵌入式C语言笔试题
- 计算直线的交点数(HDU 1466)
- 内核异常分析(访问了空指针)
- baksmali 使用
- servlet生命周期
- Java正则表达式详解
- 几道经典笔试题目
- JavaScript基础学习笔记(二)——JavaScript 注释、JavaScript 变量、JavaScript运算符
- jsp内置对象
- String StringBuffer StringBuilder的区别
- 5款整站下载工具
- Java基础好文收集
- java正则表达式验证手机号码ip,邮箱
- 学习cocoa和cocoa touch
- Comparison of Heap-Organized Tables with Index-Organized Tables