看到这道题,最初始想到的是常规方法,利用for循环遍历字符串,然后检查相应字符串中有没有重复字符,若有,则从当前字符的下一位开始继续循环。代码如下:
public class Solution{
public int lengthOfLongestSubstring(String s) {
String tmp,res="";
//要考虑字符串为空或者长度为1的时候
if(s.length() < 2){
return s.length();
}
for(int i=0;i < s.length()-1;i++){
tmp = findpart(s.substring(i));
if(tmp.length() > res.length()){
res = tmp;
}
}
return res.length();
}
//判断source字符串中是否含有target
public Boolean findstr(String source, String target){
for(int i=0;i < source.length();i++){
if(source.substring(i,i+1).equals(target)){
return true;
}
}
return false;
}
//返回字符串str中的第一个无重复部分的字符串
public String findpart(String str){
for(int i=0;i < str.length()-1;i++){
if(findstr(str.substring(0,i+1),str.substring(i+1,i+2))){
return str.substring(0,i+1);
}
}
return str;
}
}
以上,是比较常规的算法,但是当字符串比较长的时候,会报Time Limit Exceeded的错误,所以需要换一种方法。待更新...
另一种方法可以利用HashMap或者HashSet等集合类,能够大大缩短程序运行时间,这里我用的是HashSet。
Set接口和List接口一样,同样继承自Collection接口。但是与List不同的是,Set接口中的元素无序。Set接口主要有两个实现类,分别是HashSet和TreeSet,其中,HashSet是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找功能。TreeSet则是以二叉树的方式来存储元素,它可以实现对集合中的元素进行排序。HashSet所存储的元素是不可重复并且无序的。利用这个特点,可以将字符串每个字符分别添加到HashSet集合类中,然后利用HashSet类中的contains()方法来确定对应位置的字符在集合中是否存在,若存在可将重复字母前面的字符都remove()掉,继续循环。代码如下:
import java.util.*;
public class Solution {
public static void main(String[] args) {
// TODO Auto-generated method stub
String x = "dvdf";
System.out.println(lengthOfLongestSubstring(x));
}
public static int lengthOfLongestSubstring(String s){
Set<Character> set = new HashSet();
int ins = 0,num = 0,tmp = 0;
while(num < s.length() && ins < s.length()){
if(!set.contains(s.charAt(num))){
set.add(s.charAt(num));
num++;
if(tmp < num - ins){
tmp = num - ins;
}
}else{
//这个地方ins的值要注意
set.remove(s.charAt(ins));
ins++;
}
}
return tmp;
}
}