1、 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!m_pRight=rh; rh-m_pLeft = root; else tail = root;2.设计包含min 函数的栈。定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素。要求函数min、push 以及pop 的时间复杂度都是O(1)。Stack is a LIFO dat
2、a structure. When some element is popped from the stack, the status will recover to the original status as before that element was pushed. So we can recover the minimum element, too. struct MinStackElement int data; int min;struct MinStack MinStackElement * data; int size; int top;MinStack MinStackI
3、nit(int maxSize) MinStack stack; stack.size = maxSize; stack.data = (MinStackElement*) malloc(sizeof(MinStackElement)*maxSize); stack.top = 0; return stack;void MinStackFree(MinStack stack) free(stack.data);void MinStackPush(MinStack stack, int d) if (stack.top = stack.size) error(“out of stack spac
4、e.”); MinStackElement* p = stack.datastack.top; p-data = d;min = (stack.top=0?d : stack.datatop-1); if (p-min d) p-min = d; top +;int MinStackPop(MinStack stack) if (stack.top = 0) error(“stack is empty!”); return stack.data-stack.top.data;int MinStackMin(MinStack stack) return stack.datastack.top-1
5、.min;3.求子数组的最大和输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。 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)
6、 if (size=0) error(“error array size”); int sum = 0; int max = - (1 31); int cur = 0; while (cur max) max = sum; else if (sum left = NULL &right=NULL) if (sum = 0) printPath(path, top);left != NULL) helper(root-left, sum, path, top);right!=NULL) helper(root-right, sum, path, top); top -;5.查找最小的k 个元素
7、输入n 个整数,输出其中最小的k 个。例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 和4。This is a very traditional question.O(nlogn): cat I_FILE | sort -n | head -n KO(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 th
8、at I dont want to write the codes.Only gives the siftup and siftdown function.*param i the index of the element in heap a0.n-1 to be sifted upvoid siftup(int a, int i, int n) while (i0) int j=(i&1=0 ? i-1 : i+1); int p=(i-1)1; if (jn & ajai) i = j; if (ai ap) swap(a, i, p); i = p; void siftdown(int
9、a, int i, int n) while (2*i+1n) int l=2*i+1; if (l+1 al+1 al) l+; if (al next != NULL) h1 = h1-next; while (h2- h2 = h2- next; return h1 = h2;/ if there could exist cycleint isJoined(Node *h1, Node * h2) Node* cylic1 = testCylic(h1); Node* cylic2 = testCylic(h2); if (cylic1+cylic2=0) return isJoined
10、Simple(h1, h2); if (cylic1=0 & cylic2!=0 | cylic1!=0 &cylic2=0) return 0; Node *p = cylic1; while (1) if (p=cylic2 | p-next = cylic2) return 1; p=p-next- cylic1 = cylic1- if (p=cylic1) return 0;Node* testCylic(Node * h1) Node * p1 = h1, *p2 = h1; while (p2!=NULL & p2-next! p1 = p1- p2 = p2- if (p1 =
11、 p2) return p1; return NULL;第8 题此贴选一些比较怪的题,由于其中题目本身与算法关系不大,仅考考思维。特此并作一题。1.有两个房间,一间房里有三盏灯,另一间房有控制着三盏灯的三个开关,这两个房间是分割开的,从一间里不能看到另一间的情况。现在要求受训者分别进这两房间一次,然后判断出这三盏灯分别是由哪个开关控制的。有什么办法呢?Skip.2.你让一些人为你工作了七天,你要用一根金条作为报酬。金条被分成七小块,每天给出一块。如果你只能将金条切割两次,你怎样分给这些工人?1+2+4;3. 用一种算法来颠倒一个链接表的顺序。现在在不用递归式的情况下做一遍。Node * rev
12、erse(Node * head) if (head = NULL) return head; if (head-next = NULL) return head; Node * ph = reverse(head-next); head-next = head;next = NULL; return ph;Node * reverseNonrecurisve(Node * head) Node * p = head; Node * previous = NULL; while (p-next = previous; previous = p; p = p- return p;用一种算法在一个
13、循环的链接表里插入一个节点,但不得穿越链接表。I dont understand what is “Chuanyue”.用一种算法整理一个数组。你为什么选择这种方法?What is “Zhengli?”用一种算法使通用字符串相匹配。What is “Tongyongzifuchuan”. a string with “*” and “?”? If so, here is the code.int match(char * str, char * ptn) if (*ptn = 0) return 1; if (*ptn = *) do if (match(str+, ptn+1) return
14、 1; while (*str != 0); return 0; if (*str = 0) return 0; if (*str = *ptn | *ptn = ?) return match(str+1, ptn+1);颠倒一个字符串。优化速度。优化空间。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;颠倒一个句子中的词的顺序,比
15、如将“我叫克丽丝”转换为“克丽丝叫我”,实现速度最快,移动最少。Reverse the whole string, then reverse each word. Using the reverseFixlen() above.void reverseWordsInSentence(char * sen) int len = strlen(sen); reverseFixlen(sen, len); char * p = str; while (*p!=0) while (*p = & *p!=0) p+; str = p; while (p!= & reverseFixlen(str, p-
16、str);找到一个子字符串。KMP? BM? Sunday? Using BM or sunday, if its ASCII string, then its easy to fast access the auxiliary array. Otherwise an hashmap or bst may be needed. Lets assume its an ASCII string.int bm_strstr(char *str, char *sub) int len = strlen(sub); int i; int aux256; memset(aux, sizeof(int),
17、256, len+1); for (i=0; ilen; i+) auxsubi = len - i; int n = strlen(str); i=len-1; while (i strj- = subk-) ; if (k0) return j+1; if (i+1n) i+=auxstri+1; else return -1;However, this algorithm, as well as BM, KMP algorithms use O(|sub|) space. If this is not acceptable, Rabin-carp algorithm can do it.
18、 Using hashing to fast filter out most false matchings.#define HBASE 127int rc_strstr(char * str, char * sub) int dest= 0; char * p = sub; int len = 0; int TO_REDUCE = 1; dest = HBASE * dest + (int)(*p); TO_REDUCE *= HBASE; len +; int hash = 0; p = str; int i=0; while (*p != 0) if (i+=len & strncmp(
19、sub, p-len+1, len) = 0) return i-len; p+;比较两个字符串,用O(n)时间和恒量空间。What is “comparing two strings”? Just normal string comparison? The natural way use O(n) time and O(1) space.int strcmp(char * p1, char * p2) while (*p1 != 0 & *p2 ! *p1 = *p2) p1+, p2+; if (*p1 = 0 & *p2 = 0) return 0; if (*p1 = 0) return -1; if (*p2 = 0) return 1; return (*
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1