Leetcode刷题——day4

腾讯50题之最长公共前缀

阿貅的目录

  • 腾讯50题之最长公共前缀
  • 前言
  • 一、题目要求
  • 二、思路分析
  • 三、题解方法(c语言)
    • 1.法一:简短但会修改原来的数据(纵向扫描)
    • 2.法二:横向扫描
    • 3.法三:初等解法(纵向扫描)
  • 总结


前言


感谢访问,你的鼓励是我前进的动力。

一、题目要求

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

二、思路分析

(此思路可用c++和java实现,本人尚未看懂源码,故后面代码使用c实现)
四种思路:
1.横向扫描
依次遍历字符串数组中的每个字符串,对于每个遍历到的字符串,更新最长公共前缀,当遍历完所有的字符串以后,即可得到字符串数组中的最长公共前缀。如果在尚未遍历完所有的字符串时,最长公共前缀已经是空串,则最长公共前缀一定是空串,因此不需要继续遍历剩下的字符串,直接返回空串即可。

2.纵向扫描
从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。

3.分治
将问题分为两个子问题,分别求解,最后合成

4.二分查找
最长公共前缀的长度不会超过字符串数组中的最短字符串的长度。用 minLength 表示字符串数组中的最短字符串的长度,则可以在[0,minLength] 的范围内通过二分查找得到最长公共前缀的长度。每次取查找范围的中间值mid,判断每个字符串的长度为mid 的前缀是否相同,如果相同则最长公共前缀的长度一定大于或等于mid,如果不相同则最长公共前缀的长度一定小于mid,通过上述方式将查找范围缩小一半,直到得到最长公共前缀的长度。

Leetcode刷题——day4_第1张图片

三、题解方法(c语言)

1.法一:简短但会修改原来的数据(纵向扫描)

思路:
将strs[0]作为返回值,保留其中相同的字符串部分,将不同部分用’\0’隔开。
优化思路:
可以设置新的字符串,利用strcpy将strs[0]复制到该字符串,然后在该字符串中修改。

char * longestCommonPrefix(char ** strs, int strsSize){
    if(strsSize==0) return "";  //如果字符串数组为空,直接返回""
    for(int i=0;i<strlen(strs[0]);i++){   //i表示列,strlen(strs[0])表示第一个字符串长度
        for(int j=1;j<strsSize;j++){    //j表示行
            if(strs[0][i]!=strs[j][i]){ //如果比较字符串的第i列不同,该列结束,直接跳出
                strs[0][i]='\0';
                break;//也可直接return strs[0];
            }
        }
    }
    return strs[0];
}

作者:cmtsa
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/cchui-zhi-sao-miao-chao-duan-dai-ma-by-cmtsa/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2.法二:横向扫描

思路:
1)开辟一段字符串空间用以保存前两个字符相同部分
2)与后面的字符串依次比较,不断更新,最后返回该字符串

char * longestCommonPrefix(char ** strs, int strsSize){
    //空时直接输出空指针
    if(strsSize==0)  return "";
    //只有一个时直接原样输出
    if(strsSize==1)  return strs[0];
    //创建一个字符数组并让其等于前两个字符的公共前缀
	char* ans=(char*)malloc(200*sizeof(char));
	for(int j=0;;j++){
        if(strs[0][j]=='\0' || strs[1][j]=='\0'){
            ans[j]='\0';
            break;
        }
		if(strs[0][j]==strs[1][j]){
			ans[j]=strs[0][j];
			ans[j+1]='\0';
		}
		else{
			ans[j]='\0';
			break;
		}
	}
    //以ans和第3到第strsSize个字符串逐位比较取公共前缀
	for(int i=2;i<strsSize;i++){
        //检测公共部分和当前字符串若一方为空则直接return空指针
		if(ans[0]=='\0' || strs[i][0]=='\0'){
			return "";    
		}
		for(int j=0;strs[i][j]!='\0' || ans[j]!='\0';j++){
			if(strs[i][j]!=ans[j]){
                ans[j]='\0';
				break;
			}
		}
	}
	return ans;
}

作者:xiezx23
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/cyu-yan-jian-dan-xun-huan-bi-jiao-by-xie-4v5w/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.法三:初等解法(纵向扫描)

思路:
1)设置新的字符串用于存储相同字符,并在原字符串数组中先找出最短的字符串
2)从头开始依次比较,最后返回

char * longestCommonPrefix(char ** strs, int strsSize){
	int len,i,j,k=0,jdg=0; //用来判断是否退出循环
	char *s ;
	s = (char *)malloc(sizeof(char) * 201);
	if (strsSize == 0) {
		s[0] = '\0';
		return s;
	}
	len = strlen(strs[0]);
	for (i = 1; i < strsSize; i++)
		if (strlen(strs[i]) < len)
			len = strlen(strs[i]);
	for (i = 0; i < len; i++) {
		for (j = 1; j < strsSize; j++) {
			if (strs[j][i] != strs[0][i]) {
				jdg = 1;
				break;
			}
		}
		if (jdg == 0)
			s[k++] = strs[0][i];
		else
			break;
	}
	s[k] = '\0';
	return s;
}

作者:island-nz
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-cbao-li-qi-j4y5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

总结

Stay hungry. Stay foolish.

你可能感兴趣的:(leetcode刷题,leetcode,c语言,程序人生)