LeetCode——14 最长公共前缀(JAVA)

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

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

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"

示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

提示:

  • 0 <= strs.length<= 200
  • 0 <= strs[i].length<= 200
  • strs[i]仅由小写英文字母组成

思路

这题看上去简单,但是坑实在是太多了,前前后后提交了7次才AC,只能说自己的心思还是不够缜密,通过率狂掉……

一开始的想法是既然是找公共子串,那不就是给定的几个字符串之间的交集嘛,于是选择了用LinkedHashSet来做,每次读入一个字符串求一下交集,结果发现自己还是太年轻,遇到诸如["aa", "aa"]这种情况就会只输出一个"a"。因此,本题并不能用集合来做,因为子串允许重复数据的存在,而集合不允许。

然后就干脆用笨办法做了:先读入一个字符串,存在sBuffer里,然后再读之后的字符串。

这里我设了一个int型变量index,用来标记最早出现的不同字符的位置,方便最后的sBuffer.delete()操作。

所以,当访问后面字符串的时候(从第二个开始),如果当前位和sBuffer的当前位一样,那说明是公共子串的一部分,直接continue即可,如果不一样,就需要更新index为当前位置,并且break掉内循环,继而读下一个字符串。

这里要注意一些有关index的逻辑问题:

  • 最好index的初值不要赋0,因为公共子串的话自然是越短越好,我们希望每次读完一个字符串的时候,index的位置更新的越前面越好,如果是0的话,碰到["aa", "aa"]这类的情况,就压根不会改变index的值,并且还进入了sBuffer.delete()操作(此时index = 0),导致最后全部删完。因此,index的初始值最好赋一个很大的数,这样每次更新就会使index越来越小,得到的也就是最终所有字符串的公共子串了。
  • 另外,在更新index的时候不能盲目更新,因为index = j这个操作是直接赋值,如果后一次读入的j反而比之前存储的index要大(也就是更靠后一点),那么就无需再更新。因为如果不判断就直接更新的话,会造成面对诸如["aac", "cab", "abb"]这样的字符串,index在读最后一个字符串时会更新在1这个位置(而实际上应该是0)。因此,更不更新index也是需要判断的。

代码

public class Solution {
	static int MAX = 123123123;
	public int findMinimumLength(String[] strs) {
		int min = strs[0].length();
		for(int i=1;i<strs.length;i++) {
			if(strs[i].length()<min) min = strs[i].length();
		}
		return min;
	}
	public String longestCommonPrefix(String[] strs) {
		StringBuffer sBuffer = new StringBuffer();
		int minLength = findMinimumLength(strs);
		int index = MAX;//记录第一个不同字符的位置
		for(int i=0;i<minLength;i++) {
			sBuffer.append(strs[0].charAt(i));
		}
		for(int i=1;i<strs.length;i++) {
			for(int j=0;j<minLength;j++) {
				if(strs[i].charAt(j)==sBuffer.charAt(j)) {
					continue;
				}
				else {
					if(j<index) index = j;//如果index的位置更前,则更新,否则不更新
					break;
				}
			}
		}
		if(index<sBuffer.length()&&strs.length>=2) {
			sBuffer.delete(index, sBuffer.length());
		}
		String answear = sBuffer.toString();
		return answear;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值