计题目解释:
"abscdas" 这个字符串两个 a 字符距离最远(距离是5),而 s 字符只是距离4.
- 也就是说拥有距离的字符至少需要出现两次
"absdakueba" 这个字符a出现三次,算最远的那两个a的距离,所以这个还是返回a字符。
思路
- 首先创建一个 maxChar存储当前拥有最长距离的字符,maxLen存储对应的长度。
- 遍历字符串,用HashSet存第一次出现的字符,当出现冲突时,说明有字符重复出现,计算距离需要获得两个值:
- 第一个值:该字符第一次出现的位置 j (需要找个结构存储它,这时我当时纠结的地方),想了两个方法:
- 第一个暴力的,直接 indexOf(当前字符)-》返回第一次出现的位置。这个每次都搜索,很花费时间。
- 于是,想到第二种,建一个数组int[256](所有字符也就256个,Ascii),出现了就存个值。O(1)的复杂度。
- 第二个值:当前出现的位置 i(这个直接就可以获得)
- 用 i - j 得出这个重复出现的字符这次的的间隔长度curMaxLen 。这个curMaxLen与maxLen比较,如果新的更长,那么替换长度,并且maxChar也换成当前的字符。
上代码
//输入是 String;输出 char
import java.util.HashSet;
public class FindLongestDistanceCharPairs {
public static char findLongestCharPairs(String str){
if (str.length() <= 1) {
return ' ';
}
int maxLen = 0;
char maxChar = ' ';
//存储当前出现过的数组,用来去重
HashSet hashSet = new HashSet();
//记录字符第一次出现的索引,直接建立一个全部字符数目大小的数组,总共也就256个。
int[] firstIndex = new int[256];
for(int i = 0;i < str.length();i++){
if(hashSet.add(str.charAt(i))){
//记录当前i对应字符第一次出现的位置
firstIndex[str.charAt(i)] = i;
}else{
//插入没成功,说明有冲突,再次出现-》计算同样两个字符间隔长度
//该冲突字符第一次出现的位置 j
int j = firstIndex[str.charAt(i)];
int curMaxLen = i - j;
if (maxLen < curMaxLen) {
maxLen = curMaxLen;
maxChar = str.charAt(i);
}
}
}
System.out.println(maxLen);
return maxChar;
}
public static void main(String[] args) {
String str = "abbacdisauhfiugiugcouiqwgdcpiqpiubqiuncidsaunbibvasidbcaqpoavj'qk[408507-25!@%#^%*%&(^()&+{{}}:LKKPHJOGOIUOPYHGIPb";
System.out.println(findLongestCharPairs(str));
}
}
复制代码