面试总结1
来源:互联网 发布:软件行业信息化建设 编辑:程序博客网 时间:2024/05/17 18:41
转载自:http://blog.csdn.net/v_july_v/article/details/68702511.把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
This is a traditional problem that can be solved using recursion.
For each node, connect the double linked lists created from left and right child node to form a full list.
5.查找最小的k 个元素
题目:输入n 个整数,输出其中最小的k 个。
例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 和4。
ANSWER:
This is a very traditional question...
O(nlogn): cat I_FILE | sort -n | head -n K
O(kn): do insertion sort until k elements are retrieved.
O(n+klogn): Take O(n) time to bottom-up build a min-heap. Then sift-down k-1 times.
So traditional that I don’t want to write the codes...
Only gives the siftup and siftdown function.
颠倒一个字符串。优化速度。优化空间。
★假设你有一个用1001 个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1 到1000(包括1000)之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。如果你在运算中使用了辅助的存储方式,那么你能找到不用这种方式的算法吗?
ANSWER:
Sum up all the numbers, then subtract the sum from 1001*1002/2.
Another way, use A XOR A XOR B = B:
int findX(int a[]) {
int k = a[0];
for (int i=1; i<=1000;i++)
k ~= a[i]~i;
}
return k;
}
★不用乘法或加法增加8 倍。现在用同样的方法增加7 倍。
ANSWER:
n<<3;
(n<<3)-n;
第10 题
翻转句子中单词的顺序。
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
例如输入“I am a student.”,则输出“student. a am I”。
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树节点的数据结构如下:
struct BSTreeNode{int m_nValue; // value of nodeBSTreeNode *m_pLeft; // left child of nodeBSTreeNode *m_pRight; // right child of node};ANSWER:
This is a traditional problem that can be solved using recursion.
For each node, connect the double linked lists created from left and right child node to form a full list.
/** * @param root The root node of the tree * @return The head node of the converted list. */BSTreeNode * treeToLinkedList(BSTreeNode * root) { BSTreeNode * head, * tail; helper(head, tail, root); return head;}void helper(BSTreeNode *& head, BSTreeNode *& tail, BSTreeNode *root) { BSTreeNode *lt, *rh; if (root == NULL) { head = NULL, tail = NULL; return; } helper(head, lt, root->m_pLeft); helper(rh, tail, root->m_pRight); if (lt!=NULL) { lt->m_pRight = root; root->m_pLeft = lt; } else { head = root; } if (rh!=NULL) { root->m_pRight=rh; rh->m_pLeft = root; } else { tail = root; }}
3.求子数组的最大和
题目:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
ANSWER:
A traditional greedy approach.
Keep current sum, slide from left to right, when sum < 0, reset sum to 0.
int maxSubarray(int a[], int size) { if (size<=0) error(“error array size”); int sum = 0; int max = - (1 << 31); int cur = 0; while (cur < size) { sum += a[cur++]; if (sum > max) { max = sum; } else if (sum < 0) { sum = 0; } } return max;}
5.查找最小的k 个元素
题目:输入n 个整数,输出其中最小的k 个。
例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 和4。
ANSWER:
This is a very traditional question...
O(nlogn): cat I_FILE | sort -n | head -n K
O(kn): do insertion sort until k elements are retrieved.
O(n+klogn): Take O(n) time to bottom-up build a min-heap. Then sift-down k-1 times.
So traditional that I don’t want to write the codes...
Only gives the siftup and siftdown function.
/** *@param i the index of the element in heap a[0...n-1] to be sifted upvoid siftup(int a[], int i, int n) { while (i>0) { int j=(i&1==0 ? i-1 : i+1); int p=(i-1)>>1; if (j<n && a[j]<a[i]) i = j; if (a[i] < a[p]) swap(a, i, p); i = p; } }void siftdown(int a[], int i, int n) { while (2*i+1<n){ int l=2*i+1; if (l+1<n && a[l+1] < a[l]) l++; if (a[l] < a[i]) swap(a, i, l); i=l; }}
颠倒一个字符串。优化速度。优化空间。
void reverse(char *str) { reverseFixlen(str, strlen(str));}void reverseFixlen(char *str, int n) { char* p = str+n-1; while (str < p) { char c = *str; *str = *p; *p=c; } }
★假设你有一个用1001 个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1 到1000(包括1000)之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。如果你在运算中使用了辅助的存储方式,那么你能找到不用这种方式的算法吗?
ANSWER:
Sum up all the numbers, then subtract the sum from 1001*1002/2.
Another way, use A XOR A XOR B = B:
int findX(int a[]) {
int k = a[0];
for (int i=1; i<=1000;i++)
k ~= a[i]~i;
}
return k;
}
★不用乘法或加法增加8 倍。现在用同样的方法增加7 倍。
ANSWER:
n<<3;
(n<<3)-n;
第9题-----------------------------------
判断整数序列是不是二元查找树的后序遍历结果
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回true,否则返回false。
例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
8
/ /
6 10
/ / / /
5 7 9 11
因此返回true。
如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。
bool verifySquenceOfBST(int squence[], int length){ if(squence == NULL || length <= 0) return false; // root of a BST is at the end of post order traversal squence int root = squence[length - 1]; // the nodes in left sub-tree are less than the root int i = 0; for(; i < length - 1; ++ i) { if(squence[i] > root) break; } // the nodes in the right sub-tree are greater than the root int j = i; for(; j < length - 1; ++ j) { if(squence[j] < root) return false; } // verify whether the left sub-tree is a BST bool left = true; if(i > 0) left = verifySquenceOfBST(squence, i); // verify whether the right sub-tree is a BST bool right = true; if(i < length - 1) right = verifySquenceOfBST(squence + i, length - i - 1); return (left && right);}
第10 题
翻转句子中单词的顺序。
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
例如输入“I am a student.”,则输出“student. a am I”。
#include<iostream>#include<string>using namespace std;class ReverseWords{public: ReverseWords(string* wo):words(wo){} void reverse_() { int length=words->size(); int begin=-1,end=-1; for(int i=0;i<length;++i){ if(begin==-1&&words->at(i)==' ') continue; if(begin==-1) { begin=i; continue; } if(words->at(i)==' ') end=i-1; else if(i==length-1) end=i; else continue; reverse__(begin,end); //1.字母翻转 begin=-1,end=-1; } reverse__(0,length-1); //2.单词翻转 }private: void reverse__(int begin,int end) // { while(begin<end) { char t=words->at(begin); words->at(begin)=words->at(end); words->at(end)=t; ++begin; --end; } } string* words;};int main(){ string s="I am a student."; ReverseWords r(&s); r.reverse_(); cout<<s<<endl; return 0;}
- 面试总结1--CVTE面试总结
- 面试总结1
- 面试总结(1)
- java面试总结1
- 面试总结1
- 面试总结1
- 计算机网络 面试总结1
- java面试总结1
- Java面试总结1
- java面试总结1
- 面试总结-1
- 面试总结(1)
- android面试总结(1)
- Spring面试总结1!
- java面试总结1
- 面试总结(1)
- c++面试总结1
- PHP面试总结-1
- Java泛型的类型擦除
- 各种屏幕分辨率
- USB协议
- android实现ViewPage效果的TabActivity
- 基于PCA的人脸检测(Matlab版代码)
- 面试总结1
- Swing中JTextField的输入/删除事件
- Ubuntu 开启SSH
- up与dup2函数介绍----转载
- android启动模式详解_大量测试心得
- 实习日志-渠道运营
- Git一个诡异错误的解决方法
- JNI
- Unable to add window is not valid; is your activity running?