转载并参考July的博客http://topic.csdn.net/u/20101126/10/b4f12a00-6280-492f-b785-cb6835a63dc9.html,万分感谢!
题目:
此贴选一些比较怪的题,由于其中题目本身与算法关系不大,仅考考思维。特此并作一题。1)有两个房间,一间房里有三盏灯,另一间房有控制着三盏灯的三个开关,
这两个房间是分割开的,从一间里不能看到另一间的情况。
现在要求受训者分别进这两房间一次,然后判断出这三盏灯分别是由哪个开关控制的。
有什么办法呢?
ANSWER:
Skip.
2)你让一些人为你工作了七天,你要用一根金条作为报酬。金条被分成七小块,每天给出一
块。
如果你只能将金条切割两次,你怎样分给这些工人?
ANSWER:
1+2+4;
1:给1/7 剩2/7和4/7
2:给2/7 找1/7 剩1/7和4/7
3:给1/7 剩4/7
4:给4/7 找1/7和2/7 剩
5:给1/7 剩2/7
6:给2/7 找1/7
7:给1/7
3)用一种算法来颠倒一个链接表的顺序。现在在不用递归式的情况下做一遍。
ANSWER:
Node * reverse(Node *head) {
if(head == NULL) return head;
if(head->next == NULL) return head;
Node *ph = reverse(head->next);
head->next->next = head;
head->next = NULL;
returnph;
}
Node *reverseNonrecurisve(Node * head) {
if(head == NULL) return head;
Node *p = head;
Node *previous = NULL;
while(p->next != NULL) {
p->next = previous;
previous = p;
p = p->next;
}
p->next = previous;
returnp;
}
4)用一种算法在一个循环的链接表里插入一个节点,但不得穿越链接表。
ANSWER:
I don’t understand whatis “Chuanyue”.
5)用一种算法整理一个数组。你为什么选择这种方法?
ANSWER:
What is “Zhengli?”
6)用一种算法使通用字符串相匹配。
ANSWER:
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 1;
} while (*str != ‘\0’);
return 0;
}
if(*str == ‘\0’) return 0;
if(*str == *ptn || *ptn == ‘?’) {
return match(str+1, ptn+1);
}
return0;
}
7)颠倒一个字符串。优化速度。优化空间。
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;
}
}
8)颠倒一个句子中的词的顺序,比如将“我叫克丽丝”转换为“克丽丝叫我”,
实现速度最快,移动最少。
ANSWER:
Reverse the wholestring, then reverse each word. Using the reverseFixlen() above.
voidreverseWordsInSentence(char * sen) {
intlen = strlen(sen);
reverseFixlen(sen, len);
char *p = str;
while(*p!=’\0’) {
while (*p == ‘ ‘ && *p!=’\0’) p++;
str = p;
while (p!= ‘ ‘ && *p!=’\0’) p++;
reverseFixlen(str, p-str);
}
}
9)找到一个子字符串。优化速度。优化空间。
ANSWER:
KMP? BM? Sunday? UsingBM or sunday, if it’s ASCII string, then it’s easy to fast access the auxiliaryarray. Otherwise an hashmap or bst may be needed. Lets assume it’s an ASCIIstring.
int bm_strstr(char *str,char *sub) {
intlen = strlen(sub);
int i;
intaux[256];
memset(aux, sizeof(int), 256, len+1);
for(i=0; i<len; i++) {
aux[sub[i]] = len - i;
}
int n= strlen(str);
i=len-1;
while(i<n) {
int j=i, k=len-1;
while (k>=0 && str[j--] == sub[k--])
;
if (k<0) return j+1;
if (i+1<n)
i+=aux[str[i+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. Using hashing to fast filter out most falsematchings.
#define HBASE 127
int rc_strstr(char *str, char * sub) {
intdest= 0;
char *p = sub;
intlen = 0;
intTO_REDUCE = 1;
while(*p!=’\0’) {
dest = HBASE * dest + (int)(*p);
TO_REDUCE *= HBASE;
len ++;
}
inthash = 0;
p =str;
inti=0;
while(*p != ‘\0’) {
if (i++<len) hash = HBASE * dest + (int)(*p);
else hash = (hash - (TO_REDUCE * (int)(*(p-len))))*HBASE + (int)(*p);
if (hash == dest && i>=len && strncmp(sub, p-len+1, len) ==0) return i-len;
p++;
}
return-1;
}
10)比较两个字符串,用O(n)时间和恒量空间。
ANSWER:
What is “comparing twostrings”? 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 != ‘\0’ && *p1 == *p2) {
p1++, p2++;
}
if(*p1 == ‘\0’ && *p2 == ‘\0’) return 0;
if(*p1 == ‘\0’) return -1;
if(*p2 == ‘\0’) return 1;
return(*p1 - *p2); // it can be negotiated whether the above 3 if’s are necessary, Idon’t like to omit them.
}
11) 假设你有一个用1001个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1到1000(包括1000)之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。如果你在运算中使用了辅助的存储方式,那么你能找到不用这种方式的算法吗?
ANSWER:
Sum up all the numbers,then subtract the sum from 1001*1002/2.
Another way, use A XOR AXOR B = B:
int findX(int a[]) {
int k= a[0];
for(int i=1; i<=1000;i++)
k ~= a[i]~i;
}
returnk;
}
12)不用乘法或加法增加8倍。现在用同样的方法增加7 倍。
ANSWER:
n<<3;
(n<<3)-n;