1、给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "accabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "aaaaa"
输出: 1
解释: 因为无重复字符的最长子串是 "a",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
public class FindSubString {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(lengthOfSubString("456aabcb2")); // 寻找第一种无重复字符子串长度
// 正对第二种情况,输出不重复最长子串和长度
Map<String , Integer> map = getMaxSubString("456aabcdd85200cb22020520");
if (map!=null) {
Set<String> substring = map.keySet();
if (substring!=null) {
for (String key : substring) {
System.out.println("subString:" + key + ",length:" + map.get(key));
}
} else {
System.out.println("subString:" + "" + ",length:" + 0);
}
} else {
System.out.println("subString:" + "" + ",length:" + 0);
}
}
private static int lengthOfSubString(String str) {
if (str == null || "".equals(str.trim())) {
return 0;
}
int index = 0;
int flag = 0;
int length = 0;
int result = 0;
int strLength = str.length();
while (index < strLength) {
// 从 flag 下标开始获取 str 字符串的第 index 个字符首次出现的下标值 pos , 如果 pos < index 说明之
// 前已经出现过了本次获取的字符,更新记录子串的长度,从新计算子串长度
int pos = str.indexOf(str.charAt(index), flag);
if (pos < index) {
// 如果 length 大于 result 则更新 result 的值为 length
if (length > result) {
result = length;
}
// 如果剩下的 str 字符从 strLength - pos - 1 开始到 strLength 没有 result 个字符,那么 result 就是所寻
// 找的子串长度值
if (result >= strLength - pos - 1) {
return result;
}
// 之前已经出现过本次获取的字符,从新计算新的子串长度
length = index - pos - 1;
// 从 flag 开始寻找新的子串
flag = pos + 1;
}
// 处理本次获取的字符结束,更新子串长度 length + 1
length ++;
// 更新 str 字符串中已经处理了 index + 1 个字符
index ++;
}
return length;
}
// 2、换一种思路,寻找字符串中最长的子串不含有重复字符的 最长子串 及其长度
private static Map<String , Integer> getMaxSubString(String str) {
if (str == null || "".equals(str.trim())) {
return null;
}
Map<String , Integer> map = new HashMap<String , Integer>();
map.clear();
int index = 0;
int flag = 0;
int length = 0;
int result = 0;
int recordIndex = 0;
int strLength = str.length();
while (index < strLength) {
// 从 flag 下标开始获取 str 字符串的第 index 个字符首次出现的下标值 pos , 如果 pos < index 说明之
// 前已经出现过了本次获取的字符,更新记录子串的长度,从新计算子串长度
int pos = str.indexOf(str.charAt(index), flag);
if (pos < index) {
// 如果 length 大于 result 则更新 result 的值为 length
if (length > result) {
result = length;
// 记录最长子串的位置.可能存在第一次有 length > result 情况,更新后,如
// 果 result >= strLength - pos - 1 不成立,下一次循环可能出现 length > result 不成立
recordIndex = index;
}
// 如果剩下的 str 字符从 strLength - pos - 1 开始到 strLength 没有 result 个字符,那么 result 就是所寻找的子串长度值
if (result >= strLength - pos - 1) {
// 这里可以简写成 String key = str.substring(recordIndex - result, recordIndex); // recordIndex 是记录最长子串最后一个字符的位置
String key = str.substring(index - result - (index - recordIndex), index - (index - recordIndex));
map.put(key, result);
return map;
}
// 之前已经出现过本次获取的字符,从新计算新的子串长度
length = index - pos - 1;
// 从 flag 开始寻找新的子串
flag = pos + 1;
}
// 处理本次获取的字符结束,更新子串长度 length + 1
length ++;
// 更新 str 字符串中已经处理了 index + 1 个字符
index ++;
}
String key = str.substring(strLength - length, strLength);
map.put(key, length);
return map;
}
}