一些数据结构的题目
1. 在二叉搜索树中找出和为某一值的所有路径并从根节点打印。
例如输入整数22 和如下二叉搜索树,则打印出两条路径:10, 12 和10, 5, 7。
10
/ \
5 12
/ \
4 7
1 #include<iostream> 2 3 using namespace std; 4 5 #define max_length 100 6 struct TreeNode { 7 int data; 8 TreeNode * left; 9 TreeNode * right; 10 }; 11 12 void printPaths(TreeNode * root, int sum); 13 void printPath(int path[], int size); 14 void helper(TreeNode * root, int sum, int path[], int top); 15 void printTree(TreeNode *root); 16 17 18 int main(){ 19 TreeNode root, five, four, seven, twelve; 20 root.data = 10; 21 five.data = 5; 22 four.data = 4; 23 seven.data = 7; 24 twelve.data = 12; 25 26 root.left = &five; 27 root.right = &twelve; 28 five.left = &four; 29 five.right = &seven; 30 31 four.left = NULL; 32 four.right = NULL; 33 34 seven.left = NULL; 35 seven.right = NULL; 36 37 twelve.left = NULL; 38 twelve.right = NULL; 39 40 printPaths(&root, 22); 41 //printTree(&root); 42 return 0; 43 } 44 45 46 47 void printPaths(TreeNode * root, int sum) { 48 int path[max_length]; 49 helper(root, sum, path, 0); 50 } 51 52 void printPath(int path[], int size){ 53 for(int i=0;i<size;i++){ 54 cout << path[i] << " "; 55 } 56 cout << endl; 57 } 58 59 void helper(TreeNode * root, int sum, int path[], int top) { 60 if(sum - root->data < 0){ 61 return; 62 } 63 path[top++] = root->data; 64 sum -= root->data; 65 66 if (root->left == NULL && root->right==NULL) { 67 if (sum == 0) 68 printPath(path, top); 69 } else { 70 if (root->left != NULL) 71 helper(root->left, sum, path, top); 72 if (root->right!=NULL) 73 helper(root->right, sum, path, top); 74 } 75 } 76 77 void printTree(TreeNode *root){ 78 if(root != NULL){ 79 cout << root->data << endl; 80 81 if(root->left != NULL){ 82 printTree(root->left); 83 } 84 85 if(root->right != NULL){ 86 printTree(root->right); 87 } 88 } 89 }
2. 求子数组的最大和,要求时间复杂度为O(n)。例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2。
1 #include<iostream> 2 3 using namespace std; 4 5 6 int maxSubarray(int a[], int size); 7 int main(){ 8 int arr[] = {1, -2, 3, 10, -5, 6}; 9 int maxSub = maxSubarray(arr, 6); 10 cout << maxSub << endl; 11 12 return 0; 13 } 14 15 int maxSubarray(int a[], int size) { 16 if (size<=0) 17 return 0; 18 int sum = 0; 19 int max = - (1 << 31); 20 int cur = 0; 21 while (cur < size) { 22 sum += a[cur++]; 23 if (sum > max) { 24 max = sum; 25 } else if (sum < 0) { 26 sum = 0; 27 } 28 } 29 return max; 30 }
3. 设计包含min 函数的栈。定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素。要求函数min、push 以及pop 的时间复杂度都是O(1)。
tips:栈区别于队列,在栈弹出元素之后,剩下的元素是该元素进入栈之前的元素。因此不影响之前的结构。但是队列就会影响。
1 struct MinStackElement { 2 int data; 3 int min; 4 }; 5 6 struct MinStack { 7 MinStackElement * data; 8 int size; 9 int top; 10 } 11 12 MinStack MinStackInit(int maxSize) { 13 MinStack stack; 14 stack.size = maxSize; 15 stack.data = (MinStackElement*) malloc(sizeof(MinStackElement)*maxSize); 16 stack.top = 0; 17 return stack; 18 } 19 void MinStackFree(MinStack stack) { 20 free(stack.data); 21 } 22 void MinStackPush(MinStack stack, int d) { 23 if (stack.top == stack.size) error(“out of stack space.”); 24 MinStackElement* p = stack.data[stack.top]; 25 p->data = d; 26 p->min = (stack.top==0?d : stack.data[top-1].data); 27 if (p->min > d) p->min = d; 28 top ++; 29 } 30 int MinStackPop(MinStack stack) { 31 if (stack.top == 0) error(“stack is empty!”); 32 return stack.data[--stack.top].data; 33 } 34 int MinStackMin(MinStack stack) { 35 if (stack.top == 0) error(“stack is empty!”); 36 return stack.data[stack.top-1].min; 37 }
4. 查找最小的k 个元素
Tips: 使用堆排序进行K次运算即可得到K个元素
5. 给你10 分钟时间,根据上排给出十个数,在其下排填出对应的十个数。要求下排每个数都是先前上排那十个数在下排出现的次数。
上排的十个数如下:
【0,1,2,3,4,5,6,7,8,9】
举一个例子,
数值: 0,1,2,3,4,5,6,7,8,9
分配: 6,2,1,0,0,0,1,0,0,0
数值: 0,1,2,3,4
分配: 2,1,2,0,0
6.翻转句子中单词的顺序。
Tips: 先翻转整个序列,然后翻转单词
7.输入一个单向链表,输出该链表中倒数第k 个结点。链表的倒数第0 个结点为链表的尾指针。
Tips: 先遍历得到链表长度,然后遍历(n-k-1)个节点得到
8. 两个无序数组,求两个数组的交集和并集
Tips:以其中一个数组为基础,遍历另外一个数组。存在则放入交集中,不存在则放入并集中。 O(m*n)
9.输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
1 #include<iostream> 2 3 using namespace std; 4 5 void find2Number(int a[], int n, int dest); 6 7 int main(){ 8 int arr[] = {1,2,4,7,11,15}; 9 int size = 6; 10 find2Number(arr,size,18); 11 12 return 0; 13 } 14 15 void find2Number(int a[], int n, int dest) { 16 int *f = a, *e=a+n-1; 17 int sum = *f + *e; 18 while (sum != dest && f < e) { 19 if (sum < dest) 20 sum = *(++f) + *e; 21 else 22 sum = *f + *(--e); 23 } 24 if (sum == dest) 25 cout << *f << " " << *e << endl; 26 }
10.在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。
1 char firstSingle(char * str) { 2 int a[255]; 3 memset(a, 0, 255*sizeof(int)); 4 char *p=str; 5 while (*p!=’\0’) { 6 a[*p] ++; 7 p++; 8 } 9 p = str; 10 while (*p!=’\0’) { 11 if (a[*p] == 1) return *p; 12 } 13 return ‘\0’; // this must the one that occurs exact 1 time. 14 }
11. 输入一个表示整数的字符串,把该字符串转换成整数并输出。例如输入字符串"345",则输出整数345。
1 int atoi(char * str) { 2 int neg = 0; 3 char * p = str; 4 if (*p == ‘-’) { 5 p++; neg = 1; 6 } else if (*p == ‘+’) { 7 p++; 8 } 9 int num = 0; 10 while (*p != ‘\0’) { 11 if (*p>=0 && *p <= 9) { 12 num = num * 10 + (*p-’0’); 13 } else { 14 error(“illegal number”); 15 } 16 p++; 17 } 18 return num; 19 }
12.
13.
14.
15.
16.
17.
18.
19.
20.
程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦