- 题目
一个含有多个空格的ASCII串,求最长非空格字符串的长度,尽可能最优。例如,输入:“aa bc aaaa aaa”,输出:4;
- 分析
首先可能想到就是直接遍历一个一个字符相同的累加 等到不同了再将统计的次数count放到maxLength 下次不同在count和maxLength做比较将最大的赋值到maxLength。但是这样复杂度是相对较高他需要所有遍历才可以得出最后结果
前提条件是含有多个空格的ASCll串所以首先想到的是可以通过空格分隔成字符数组,然后写个字符串排序器按照字符长度从大到小。这样排序的好处的可以从字符数组长的先递归判断连续出现次数。根据出现次数和后面的长度做比较大于等于的话 就可以不用继续递归遍历字符串数组。减少时间复杂度达到最优可能。
- 源码实现
自定义的字符串长度比较器
/**
* @ClassName SortByLengthComparator
* @Description: TODO
* @Author drj
* @Date 2021/3/13
* @Version V1.0
**/
public class SortByLengthComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return o2.length() - o1.length();
}
}
递归实现统计次数
package org.cloud_common.practice;
import cn.hutool.core.lang.Console;
import com.thoughtworks.xstream.mapper.Mapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName FindMostSameStr
* @Description: TODO
* @Author drj
* @Date 2021/3/13
* @Version V1.0
**/
public class FindMostSameStr {
/**
* 遍历次数
*/
private static Integer num = 0;
/**
* 返回最大的出现次数
*/
private static Integer temp = 1;
public static void main(String[] args) {
String s = "aaa aac drc peo";
int mostCountWithSameStr = getMostCountWithSameStr(s);
System.out.println("最大长度:" + mostCountWithSameStr);
System.out.printf("num = " + num);
}
/**
* 获取字符最大的连续次数
*/
public static int getMostCountWithSameStr(String str) {
String[] list = str.split(" ");
List<String> strings = Arrays.asList(list);
strings.sort(new SortByLengthComparator());
Console.log("排序输出:{}",strings);
for(String s : strings){
int length = s.length();
int sameSubStringCount = getSameSubStringCount(s, 1, 1, 1);
if(sameSubStringCount > temp ){
temp = sameSubStringCount;
}
if(temp >= length){
return temp;
}
}
return temp;
}
/**
* 递归实现每个字符统计次数返回最大
* @param str 目标字符串
* @param currentPos 当前位置
* @param count 当前字符出现次数
* @param maxLength 最大次数
* @return
*/
public static int getSameSubStringCount(String str, int currentPos, int count, int maxLength){
if(currentPos == str.length()){
return maxLength;
}
num++;
if(str.charAt(currentPos) == str.charAt(currentPos - 1)){
count++;
if(count > maxLength){
maxLength = count;
}
}else{
count = 1;
}
return getSameSubStringCount(str, currentPos + 1, count, maxLength);
}
}
在回顾上面实现过程发现需要排序 然后递归同时需要string 数组集合时间复杂度和空间复杂度依然可以优化,然后还有split 方法(虽然有替代的方法)也是会耗性能。所以我们采用最原始的做法遍历找最大值时间复杂度n 空间复杂度1。
- 第二种优化方案
private static String s = "aa bc aaaa aaa";
public static void main(String[] args) {
/**
* 存放最大长度的值
*/
int max = 0;
/**
* 临时存放的值
*/
int j = 0;
for(int i = 0; i < s.length(); i++){
if(Character.isWhitespace(s.charAt(i))){
max = Math.max(max,j);
j = 0;
}else if(s.length() == i+1){
max = Math.max(max,j);
}else{
j++;
}
}
System.out.println("最大长度:" + max);
}