面试100题:8.杂题(先占位)

来源:互联网 发布:hadoop书籍 知乎 编辑:程序博客网 时间:2024/04/30 10:36

转载并参考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;

原创粉丝点击