简介
最近尝试下大家口口相传的神器 leetcode-cn.com,大家自己注册就可以选择题库进行使用了。我都会先自己出一个答案,然后再学习别人的标准答案,进行自我提升。
题目
个人答案及结果
我直接把相关注释再代码体现出来
public static void main(String[] args) {
String[] strs = {"flower", "flow", "flight"};
System.out.println("结果:" + longestCommonPrefix(strs));
}
public static String longestCommonPrefix(String[] strs) {
//用来作为返回公缀使用
//数组数量不固定,也没有next方法,只能与上一个进行比较
String last = null;
//防止数组空
if (strs.length == 0) {
return "";
}
//遍历数组
for (String str : strs) {
//字符串操作方便
StringBuffer a = new StringBuffer();
//数组第一个元素没有上一个,不进行比较,直接跳过,防止数组只有一个元素,所以直接给公缀赋值
if (last == null) {
last = str;
} else {
//字符串遍历操作
char[] ca = last.toCharArray();
char[] cb = str.toCharArray();
//以短的为准,防止越界
int length = ca.length < cb.length ? ca.length : cb.length;
for (int i = 0; i < length; i++) {
//因为需求是前缀,第一个都不同后面就免了
if (i == 0 && ca[i] == cb[i]) {
a.append(ca[i]);
}
//防止出现间隔相同这种情况,如: abc ,adc这种。
else if (ca[i] == cb[i] && a.length() == i) {
a.append(ca[i]);
} else {
break;
}
}
//赋值
last = a.toString();
}
}
return last;
}
学习一下官方的
了不得啊,官方给了三种方案 最长公共前缀-官方答案(视频)
简单介绍一下
-
水平扫描法,就是我上面写的
-
分治法
先遍历前半部分,后遍历后半部分
代码
/**
* 分治法(先遍历前半部分,后遍历后半部分)
*/
public static String longestCommonPrefix2(String[] strs) {
//防止数组空
if (strs.length == 0) {
return "";
}
//用来作为返回公缀使用
//数组数量不固定,也没有next方法,只能与上一个进行比较
//数组前半部分的结果
String last = commonPrefix(strs, 0, strs.length / 2);
if (last.equals("")) {
return "";
}
//数组后半部分的结果
String next = commonPrefix(strs, strs.length / 2, strs.length - 1);
//两个结果比较
return commonPrefix(new String[]{last, next}, 0, 1);
}
public static String commonPrefix(String[] strs, int begin, int end) {
String last = strs[begin];
//遍历数组,与上一个进行比较,所以从第二个开始
for (int a = begin + 1; a <= end; a++) {
//字符串操作方便
StringBuffer common = new StringBuffer();
//字符串遍历操作
char[] ca = last.toCharArray();
char[] cb = strs[a].toCharArray();
//以短的为准,防止越界
int length = ca.length < cb.length ? ca.length : cb.length;
for (int i = 0; i < length; i++) {
//因为需求是前缀,第一个都不同后面就免了
if (i == 0 && ca[i] == cb[i]) {
common.append(ca[i]);
}
//防止出现间隔相同这种情况,如: abc ,adc这种。
else if (ca[i] == cb[i] && common.length() == i) {
common.append(ca[i]);
} else {
break;
}
}
//赋值
last = common.toString();
}
return last;
}
- 二分法
找到最短的字符串,分为两个字符串,分别与所有字段比较
/**
* 二分法官方(找到最短的字符串,分为两个字符串,分别与所有字段比较)
*/
public static String longestCommonPrefix4(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
int minLength = Integer.MAX_VALUE;
for (String str : strs) {
minLength = Math.min(minLength, str.length());
}
int low = 0, high = minLength;
while (low < high) {
int mid = (high - low + 1) / 2 + low;
if (isCommonPrefix(strs, mid)) {
low = mid;
} else {
high = mid - 1;
}
}
return strs[0].substring(0, low);
}
public static boolean isCommonPrefix(String[] strs, int length) {
String str0 = strs[0].substring(0, length);
int count = strs.length;
for (int i = 1; i < count; i++) {
String str = strs[i];
for (int j = 0; j < length; j++) {
if (str0.charAt(j) != str.charAt(j)) {
return false;
}
}
}
return true;
}