出题:数组中有一个数字出现的次数超过了数组长度的一半,请找出这个数字;
分析:
解题:
1 int HalfElementArray(int *array, int length) { 2 int num=array[0]; 3 int count=1; 4 5 for(int i=1;i<length;i++) { 6 if(array[i]==num) 7 count++; 8 else { 9 if(count==0) 10 num=array[i+1]; 11 else 12 count--; 13 } 14 } 15 return num; 16 } 17 void QuarterElementsArray(int *array, int length) { 18 int num1=array[0],num2=array[1],num3=array[2]; 19 int count1=0,count2=0,count3=0; 20 21 for(int i=3;i<length;i++) { 22 if(array[i]==num1) 23 count1++; 24 else if(array[i]==num2) 25 count2++; 26 else if(array[i]==num3) 27 coun3++; 28 else { 29 if(count1==0) 30 num1=array[i+1]; 31 else if(count2==0) 32 num2=array[i+1]; 33 else if(count3==0) 34 num3=array[i+1]; 35 else { 36 num1--;num2--;num3--; 37 } 38 } 39 printf("%D, %d, %d\n",num1,num2,num3); 40 } 41 }
出题:给定一棵二叉树,以及两个节点,要求找到两个节点最近的公共父节点;
分析:
解题:
1 struct Node { 2 int value; 3 Node *left; 4 Node *right; 5 }; 6 7 /** 8 * 使用stack结构保存root到target节点的路径的解法 9 * 算法复杂度为O(N),空间复杂度为O(NlogN) 10 * */ 11 12 /** 13 * stack实现 14 * */ 15 class MyStack { 16 private: 17 Node **array; 18 int capability; 19 int top; 20 public: 21 MyStack(int cap=5): array((Node**)malloc(sizeof(Node)*cap)), capability(cap), top(0) {} 22 ~MyStack() {delete [] array;} 23 24 bool isFull() { 25 return top == capability; 26 } 27 bool isEmpty() { 28 return top == 0; 29 } 30 int freeSlot() { 31 return capability - top; 32 } 33 34 /** 35 * top当前的位置就是下一个push元素所在的slot 36 * */ 37 bool push(Node *n) { 38 if(isFull()) return false; 39 array[top++]=n; 40 return true; 41 } 42 bool pop(Node **n) { 43 if(isEmpty()) return false; 44 *n=array[--top]; 45 return true; 46 } 47 void ShowStack() { 48 int temp=top-1; 49 printf("\n"); 50 for(int i=0;i<=temp;i++) 51 printf("%d, ",array[i]->value); 52 printf("\n"); 53 } 54 }; 55 56 Node* GetLowerFather(MyStack *sfirst, MyStack *ssecond) { 57 58 } 59 60 bool FindTargetPath(Node *root, Node *target, MyStack *mstack) { 61 if(root==NULL) 62 return false; 63 mstack->push(root); 64 65 if(root==target) 66 return true; 67 else if(FindTargetPath(root->left,target, mstack)) 68 return true; 69 else if(FindTargetPath(root->right,target, mstack)) 70 return true; 71 else { 72 mstack->pop(NULL); 73 return false; 74 } 75 } 76 77 Node* FindCommonFather1(Node *root, Node *first, Node *second) { 78 if(first==NULL || second==NULL) 79 return NULL; 80 MyStack *sfirst=new MyStack(10); 81 MyStack *ssecond=new MyStack(10); 82 83 if(FindTargetPath(root, first, sfirst) && 84 FindTargetPath(root, second, ssecond)) 85 return GetLowerFather(sfirst, ssecond); 86 else { 87 printf("\nbad input"); 88 return NULL; 89 } 90 } 91 92 /** 93 * 直接使用递归的解法 94 * 算法复杂度为O(N^2) 95 * */ 96 97 bool HasNode(Node *root, Node *target) { 98 if(root==NULL) return false; 99 if(root==target) return true; 100 /** 101 * 仅当左子树没有找到target的时候,才处理右子树 102 * */ 103 bool bleft=HasNode(root->left,target); 104 if(!bleft) { 105 return HasNode(root->right,target); 106 } else { 107 return true; 108 } 109 } 110 111 Node* FindCommonFather(Node *cur, Node *first, Node *second) { 112 /** 113 * 如果当前节点为NULL,返回NULL 114 * */ 115 if(cur == NULL) return NULL; 116 /** 117 * 判断是否first和second都在左子树 118 * 注意处理first和second为同一个节点的情况 119 * 注意处理first和second中一个节点是另一个节点的父节点的情况 120 * */ 121 bool bfirstleft=false, bsecondleft=false; 122 if(cur->left != NULL) { 123 bfirstleft=HasNode(cur->left,first); 124 bsecondleft=HasNode(cur->left,second); 125 if(bfirstleft && bsecondleft) { 126 /** 127 * 这里的||操作可以处理当一个节点是另一个节点的 128 * 父节点的情况 129 * */ 130 if(cur->left==first || cur->left==second) 131 return cur; 132 else 133 return FindCommonFather(cur->left,first,second); 134 } 135 } 136 /** 137 * 判断是否first和second都在右子树 138 * 注意处理first和second为同一个节点的情况 139 * 注意处理first和second中一个节点是另一个节点的父节点的情况 140 * */ 141 bool bfirstright=false, bsecondright=false; 142 if(cur->right != NULL) { 143 bfirstright=HasNode(cur->right,first); 144 bsecondright=HasNode(cur->right,second); 145 if(bfirstright && bsecondright) { 146 /** 147 * 这里的||操作可以处理当一个节点是另一个节点的 148 * 父节点的情况 149 * */ 150 if(cur->right==first || cur->right==second) 151 return cur; 152 else 153 return FindCommonFather(cur->right,first,second); 154 } 155 } 156 /** 157 * 判断是否first在左且second在右,或者first在右且 158 * second在左 159 * */ 160 if((bfirstleft && bsecondright) || 161 (bfirstright && bsecondleft)) 162 return cur; 163 return NULL; 164 }
笔试算法题(24):找出出现次数超过一半的元素 & 二叉树最近公共父节点,布布扣,bubuko.com
笔试算法题(24):找出出现次数超过一半的元素 & 二叉树最近公共父节点
原文:http://www.cnblogs.com/leo-chen-2014/p/3745075.html