定义一个栈的数据结构,实现min函数,要求push,pop,min时间复杂度是0(1);找出字符串中的最长子串,要求子串不含重复字符,时间复杂度是O(n);
2012-10-23 20:22
1131 查看
1.将IPV4转换成整数,要求高效。
2.定义一个栈的数据结构,实现min函数,要求push,pop,min时间复杂度是0(1);
3.数组a
里存有1到n的所有数,除了一个数removed,找出这个missing的数。
4.找出字符串中的最长子串,要求子串不含重复字符,时间复杂度是O(n);
第一题答案:
第二题答案:
第四题其实很有难度,有好几种解法。
方法一:穷举法,使用2重外循环遍历所有的区间,用2重内循环检验子串是否符合“无重复字符”这一要求。其中外层循环i、j 遍历所有的下标,m、n是内层循环,检查区间[i,j]是否符合要求。空间复杂度是O(1),时间复杂度O(N^4)。
方法二:对方法一的检验子串是否“无重复字符”进行改进,使用hash表记录字符是否出现过。
方法三:对字符串“axbdebpqawuva”构造下表:
表中,字符串有3个‘a’,有2个‘b’,其余为单一字符。next[]记录了下一个与之重复的字符的位置,如str[0]=str[8]=str[12]=‘a’,这时next[0]=8,next[8]=12,next[12]=13,其余同理。值得注意的是,对于没有重复字符的,next[]存储字符结束符‘\0’的下标,即13。
这里,first[i]表示i之后,第一次出现重复字符的那个位置。例如,str[0]之后,第一次出现的重复字符是str[5]=‘b’,当然,从str[1],str[2]开始也是一样。而从str[3]开始,要到str[12]才出现重复字符‘a’。可以证明,从str[i]起的最长符合要求的长度为first[i]-i,区间为[i,first[i]-1]由此得解。上述最长串是当i=3时,first[i]-i=12-3=9。结果最长无重复子串为“debpqawuv”。
方法四:使用后缀数组
对这个字符串构造后缀数组,在每个后缀数组中,寻找没有重复字符的最长前缀,最长的前缀就是要找的子串。
进一步精简:
2.定义一个栈的数据结构,实现min函数,要求push,pop,min时间复杂度是0(1);
3.数组a
里存有1到n的所有数,除了一个数removed,找出这个missing的数。
4.找出字符串中的最长子串,要求子串不含重复字符,时间复杂度是O(n);
第一题答案:
#include<stdio.h> int change(char *a) { unsigned int n = 0,sum = 0,i = 2; int m[] = {256,256*256,256*256*256}; while(*a != '\0') { if(*a != '.') { n = n*10 + *a - '0'; } if(*a == '.') { sum = sum + n * m[i--]; n = 0; } a++; } sum = sum + n; return sum; } int main(int argc,char *argv[]) { char ip[] = "192.168.23.7"; unsigned int n; n = change(ip); printf("192.168.23.7->%u\n",n); return 0; }
第二题答案:
#include<stdio.h> #define STACK_LEN 50 typedef struct { int data; int min; }stackitem; typedef struct { stackitem data[STACK_LEN]; int top; }stack; void push(stack *s,int val) { s->data[s->top].data = val; if(s->top > 0) // 保证栈顶元素中的min始终为当前栈中最小值 { if(val < s->data[s->top-1].min) // 如果当前push进的元素小于栈中最小元素值 s->data[s->top].min = val; // 把当前元素置为栈中最小元素值 else s->data[s->top].min = s->data[s->top-1].min; } else // 否则,不更新 s->data[s->top].min = val; s->top++; } int pop(stack *s) { if(s->top-1 >= 0) return s->data[--s->top].data; else return -1; } int min(stack*s) { if(s->top-1 >= 0) return s->data[s->top-1].min; else return -1; } int main(int argc,char *argv[]) { stack *s; push(s,1); push(s,2); printf("%d\n",min(s)); printf("%d\n",pop(s)); return 0; }
第四题其实很有难度,有好几种解法。
方法一:穷举法,使用2重外循环遍历所有的区间,用2重内循环检验子串是否符合“无重复字符”这一要求。其中外层循环i、j 遍历所有的下标,m、n是内层循环,检查区间[i,j]是否符合要求。空间复杂度是O(1),时间复杂度O(N^4)。
//O(N^4)的时间复杂度 #include<stdio.h> int max_unique_substring1(char * str) { int maxlen = 0; int begin = 0; int n = strlen(str); int i,j,m; for(i=0; i<n; ++i) for(j=1; j<n; ++j) { int flag = 0; for(m=i; m<=j; ++m) { int n; for(n=m+1; n<=j; ++n) { if(str == str[m]) { flag = 1; break; } } if(flag == 1) break; } if(flag==0 && j-i+1>maxlen) { maxlen = j-i+1; begin = i; } } printf("%.*s\n",maxlen,&str[begin]); return maxlen; } int main(int argc,char *argv[]) { char *str = "abcdafeeg"; printf("%d\n",max_unique_substring1(str)); return 0; }
方法二:对方法一的检验子串是否“无重复字符”进行改进,使用hash表记录字符是否出现过。
//O(N^2)的时间复杂度 #include<stdio.h> int max_unique_substring2(char * str) { int i,j; int begin; int maxlen = 0; int hash[256]; int n = strlen(str); for(i=0; i<n; ++i) { memset(hash,0,sizeof(hash)); hash[str[i]] = 1; for(j=i+1; j<n; ++j) { if(hash[str[j]] == 0) hash[str[j]] = 1; else break; } if(j-i > maxlen) { maxlen = j-i; begin = i; } } printf("%.*s\n", maxlen, &str[begin]); return maxlen; } int main(int argc,char *argv[]) { char *str = "abcdafeeg"; printf("%d\n",max_unique_substring2(str)); return 0; }
方法三:对字符串“axbdebpqawuva”构造下表:
表中,字符串有3个‘a’,有2个‘b’,其余为单一字符。next[]记录了下一个与之重复的字符的位置,如str[0]=str[8]=str[12]=‘a’,这时next[0]=8,next[8]=12,next[12]=13,其余同理。值得注意的是,对于没有重复字符的,next[]存储字符结束符‘\0’的下标,即13。
这里,first[i]表示i之后,第一次出现重复字符的那个位置。例如,str[0]之后,第一次出现的重复字符是str[5]=‘b’,当然,从str[1],str[2]开始也是一样。而从str[3]开始,要到str[12]才出现重复字符‘a’。可以证明,从str[i]起的最长符合要求的长度为first[i]-i,区间为[i,first[i]-1]由此得解。上述最长串是当i=3时,first[i]-i=12-3=9。结果最长无重复子串为“debpqawuv”。
//O(N)的时间复杂度 #include<stdio.h> int max_unique_substring3(char * str) { int maxlen = 0; int begin = 0; int n = strlen(str); int * next = (int*)malloc(sizeof(int)*n); //next[i]记录了下一个与str[i]重复的字符的位置 int * first = (int*)malloc(sizeof(int)*(n+1)); //first[i]记录str[i]后面最近的一个重复点 int hash[256]; memset(hash,n,sizeof(hash)); first = n; int i; for(i=n-1; i>=0; i--) { next[i] = hash[str[i]]; hash[str[i]] = i; if (next[i] < first[i+1]) first[i] = next[i]; else first[i] = first[i+1]; //生成first[]表,复杂度是O(N)的 } for(i=0; i<n; i++) { if (first[i]-i > maxlen) { maxlen = first[i]-i; begin = i; } } free(first); free(next); printf("%.*s\n", maxlen, &str[begin]); return maxlen; } int main(int argc,char *argv[]) { char *str = "axbdebpqawuva"; printf("%d\n",max_unique_substring3(str)); return 0; }
方法四:使用后缀数组
对这个字符串构造后缀数组,在每个后缀数组中,寻找没有重复字符的最长前缀,最长的前缀就是要找的子串。
#include<stdio.h> //得到字符串最长的无重复的前缀长度 int longestlen(char * p) { int hash[256]; int len = 0; memset(hash,0,sizeof(hash)); while(*p && !hash[*p]) { hash[*p] = 1; ++len; ++p; } return len; } //使用后缀数组解法 int max_unique_substring4(char * str) { int maxlen = -1; int begin = 0; char *a[999]; int n = 0; while(*str != '\0') { a[n++] = str++; } int i; for (i=0; i<n; i++) { int temlen = longestlen(a[i]); if (temlen > maxlen) { maxlen = temlen; begin = i; } } printf("%.*s\n", maxlen, a[begin]); return maxlen; } int main(int argc,char *argv[]) { char *str = "abcdafeeg"; printf("%d\n",max_unique_substring4(str)); return 0; }
进一步精简:
#include<stdio.h> //得到字符串最长的无重复的前缀长度 int longestlen(char * p) { int hash[256]; int len = 0; memset(hash,0,sizeof(hash)); while(*p && !hash[*p]) { hash[*p] = 1; ++len; ++p; } return len; } //使用后缀数组解法 int max_unique_substring4(char * str) { char *p=str; int maxlen = -1; int begin = 0; int i; for (i=0; i<strlen(p); i++) { int temlen = longestlen(str+i); if (temlen > maxlen) { maxlen = temlen; begin = i; } } printf("%.*s\n", maxlen, p+begin); return maxlen; } int main(int argc,char *argv[]) { char *str = "abcdafeeg"; printf("%d\n",max_unique_substring4(str)); return 0; }
相关文章推荐
- 定义一个栈的数据结构,实现min函数,要求push,pop,min时间复杂度是0(1);找出字符串中的最长子串,要求子串不含重复字符,时间复杂度是O(n);
- 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)
- 实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1) /查找一个字符串中第一个只出现两次的字符
- 面试题:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素,要求函数min,push及pop的时间复杂度都是O(1)
- 定义一个栈的数据结构,要求实现一个min函数,每次能够得到栈的最小值,并且要求Min的时间复杂度为O(1)
- 【数据结构】实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 定义一个栈的数据结构,要求实现一个min函数,每次能够得到栈的最小值,并且要求Min的时间复杂度为O(1)
- 定义栈的数据结构,要求添加一个 min 函数,能够得到栈的最小元素。要求函数 min、push 以及 pop 的时间复杂度都是 O(1)。
- 实现一个栈,要求pop,push,Min,时间复杂度为O(1)
- 定义栈的数据结构在Theta(1)时间复杂度内实现min,pop,push操作
- 定义一个栈的数据结构,要求实现一个min函数,每次能够得到栈的最小值,并且要求Min的时间复杂度为O(1)
- 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
- 构造栈的数据结构,要求实现min函数,通过min函数取得栈中的最小值。要求PUSH, POP, MIN的时间复杂度为O(1)
- 实现一个栈,要求push,pop,Min的操作时间复杂度为O(1)
- 实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 【每日一题】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 找出一个字符串中出现的重复的最长的字符子串
- 剑指offer 21---实现一个栈, 要求实现Push( 出栈) 、 Pop( 入栈) 、 Min( 返回最小值的操作) 的时间复杂度为O(1)
- 【每日一题】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、 Min(返回最小值的操作)的时间复杂度为O(1)