letCode 無重複字符的最長子串 複雜度O(n)
方法一
看到這一題的時候,首先想到的方法是用LinkList按序存儲每一符號(下標和char符號),遍歷到某個字符時,判斷當前字符是否已經存儲在鏈表中。
(1)字符不在鏈表,則將其加入鏈表的最後
(2)字符已經在鏈表中,判斷當前鏈表大小,若值大於max,則更新max值。並將鏈表中該字符所在節點及其前面的結點從鏈表移除,再將字符及其在字符串中的位置信息結點添加到鏈表最後
如此最終求得最大值,但是此種方法超時了。代碼如下
class Solution {
class Node{
char c;
int index;
public Node(char c,int index) {
this.c=c;
this.index=index;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Node) {
}
return super.equals(obj);
}
}
private int getIndex(List<Node> nodes,char v) {
int i=0;
for (Node n:nodes) {
if (n.c==v) {
return i;
}
i++;
}
return -1;
}
public int lengthOfLongestSubstring(String s) {
char[] str=s.toCharArray();
List<Node> nodes=new LinkedList<>();
// Map< Character, Integer> map=new HashMap<Character, Integer>();
int len=0,max=0;
for(int i=0;i<str.length;i++) {
int index=getIndex(nodes, str[i]);
if (index!=-1) {
if(len>max) {
max=len;
}
nodes=nodes.subList(index+1, nodes.size());
len=1+nodes.size();
nodes.add(new Node(str[i],i));
// System.out.println("("+i+","+str[i]+"+)"+"node = ");
// for (Node n:nodes){
// System.out.print(n.c+" ");
// }
// System.out.println("len="+len);
}else {
len++;
nodes.add(new Node(str[i],i));
}
}
if(len>max)max=len;
return max;
}
}
方法二
在看到超時的那一組數據,發現基本字符都是在128個ASCII中的,於是就想直接用一個128長度的數組去存儲,數組的值默認爲-1 ,即沒有被訪問過。
當掃描到當前字符時
(1)若該字符 被訪問過了,且在當前範圍內,則比較len和max大學,更新max值。再重置範圍,以上次被訪問的下一位爲範圍,再將字符指向的下標改爲當前下標。
(2)字符沒被訪問過,或者不在當前範圍,將其所 指向的下標更新爲當前下標。
隨機訪問的速度基本可以認爲是o(1)的。遍歷字符O(n).
因此時間複雜度爲O(n).
代碼如下
public class Soulution {
public int lengthOfLongestSubstring(String s) {
int max=0,len=0;
char[] str=s.toCharArray();
int cArray[]=new int[128];
// 當前訪問的下標 當前範圍最左邊字符下標
int currentIndex=0,leftIndex=-1;
for (int i=0;i<cArray.length;i++)cArray[i]=-1;
for (char c:str) {
// 當前字符上次訪問時所在下標
int lastVisitIndex =cArray[(short)c];
// 該字符被訪問過,且該字符上次被訪問所在位置在 當前所求範圍內
if(lastVisitIndex!=-1 && lastVisitIndex>=leftIndex){
if (len>max)max=len;
leftIndex=lastVisitIndex+1;
len=currentIndex-leftIndex+1;
}else {
len++;
}
cArray[(short)c]=currentIndex;
currentIndex++;
}
if(len>max)max=len;
return max;
}