前言
本文介绍将要介绍贪心算法以及使用贪心算法对一个字符串数组进行拼接后获得最小字典序字符串的题目的思路分析以及代码实现。
正文
给出一个由字符串组成的数组strs,然后把所有的字符串拼接起来,返回所有可能的拼接结果中字典序最小的结果。字典序就是按字典字母排序。
贪心算法
贪心算法是具有最自然智慧的算法,他是一种用局部最功利的标准总是做出在当前看来是最好的选择,贪心算法的难点在于证明局部最公里的标准可以得到全局最优解。
举个例子来说,有人提出一个话题,什么样的手机是好手机?不同的人会给出不同的答案,比如像素高的、流畅的、性能好的、盐值高的等等,每一个答案可能都是对的,这些答案都是从局部出发视图去覆盖全局,因此需要从这些答案里要找出一个最优的,这个最优的就是有效的贪心策略。
对于贪心算法的学习主要以增加阅历和经验为主,有时候想到的贪心策略不一定是最优解,这样就会导致解题失败,有人会说贪心策略十贪九错,所以说小贪怡情,大贪伤心啊~
思路分析
再来看这道题目,字典序是什么呢?就是我们在编程时常见的字符串排序,从每个字符串的高位到地位,依次按字母顺序比较。
假设有个字符串数组为["abc","cde","fgh"],在字符串拼接时拼接结果abccdefgh就应该是字典序最小的,其他的结果abcfghcde、cdeabcfgh等都会比abccdefgh大。
看到这里,是不是觉得将字符串按字符串排序后,拼接起来就是最优解了?其实不是的,我们来看个例子b、ba这两个字符串的拼接排序,这两个字符串按字典排序后拼接后为bba,但是这个结果并不是最优解,最优解应该是bab。所以说,按字典排序后拼接这个贪心策略是错误的。
那么这道题目的贪心点在哪里呢?
刚才b、ba这两个字符串可以理解为字符串a和字符串b比较大小,谁小谁在前面,我们可以换个思路,让两个字符串先通过组合方式拼接起来,比如让字符串ab和字符串ba比较大小,谁小谁在前面,这样不就可以了吗。
同理,当字符串有3个、4个或更多的时候,多个字符串拼接产生的结果对比下,结果和两个字符串是一样的,比如3个字符串拼接可以看做是两个字符串拼接后,再和第3个字符串拼接。
代码实现
根据上面的分析,我们来看下代码实现,对于字符串拼接后对比,所以需要定义一个比较器,代码如下:
public class MyComparator implements Comparator<String> {
@Override
public int compare(String a, String b) {
return (a + b).compareTo(b + a);
}
}
接下来的步骤就比较简单了,就是对字符串进行排序,然后进行拼接即可,代码如下:
public String lowestString(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
Arrays.sort(strs, new MyComparator());
String res = "";
for (int i = 0; i < strs.length; i++) {
res += strs[i];
}
return res;
}
啥?字符串拼接应该使用StringBuilder。这个不是重点,不要在意这些细节~
总结
本文介绍了贪心算法以及使用贪心算法对一个字符串数组进行拼接后获得最小字典序字符串的题目解法,其实也可以使用暴力递归,不过不是本文的重点,这里就不先介绍了。