

요소 간 중복을 체크하고, 중복 발생 시 순회 중단
- 구현은 stream().boxed().anyMatch(x->x~)을 사용
visited배열로 방문 여부 체크
중복없을 시 curr리스트에 추가
모든 문자 요소를 start로 지정해 경우의 수 돌아야하기 때문에
for문 내 백트래킹 호출
import java.util.*;
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<ArrayList<Character>> comb = new HashSet<>();
for(int i=0;i<s.length();i++){
boolean[] visited = new boolean[s.length()];
backtracking(s,i,comb,visited,new ArrayList<>());
}
System.out.println(comb);
int max=0;
for(ArrayList<Character> c:comb){
max=Math.max(max,c.size());
}
return max;
}
public void backtracking(String s,int start,Set<ArrayList<Character>> comb,boolean[] visited,ArrayList<Character> curr){
if(curr.size()>0 && curr.size()<=s.length()){
comb.add(new ArrayList<>(curr));
return;
}
for(int i=start;i<s.length();i++){
if(!visited[i]){
char c = s.charAt(i);
if(curr.size()>0){
if(!curr.stream().anyMatch(ch -> ch==c)){
curr.add(c);
visited[i]=true;
}else return;
}else{
curr.add(c);
visited[i]=true;
}
backtracking(s,i+1,comb,visited,curr);
}
}
}
}

중복 문자를 발견하면, 그 중복 문자 다음으로 아예 시작 위치를 옮기는 것.
어차피 더이상 순회 안함 + 새로운 배열 갱신 + 그 중에서 길이 최대 구하는 게 목적이기 떼문에 투 포인터로 풀어도 충분
문자 길이 세기 = right-left +1
-인덱스가 0부터 시작되기 때문에 +1해주어야 길이 나옴
문자열의 중복 여부를 체크할 때는 ASCII 배열 (최대 128) 만들어 문자 자체를 인덱스로 지정하고 해싱 기법으로 문자의 위치를 저장
중복 발견 전까지는 계속 문자를 더해가며 순회하다가, 중복 발견하면 그 즉시 다음 인덱스로 left포인트를 이동시킴.
순회 반복
import java.util.*;
class Solution {
public int lengthOfLongestSubstring(String s) {
int[] lastPosition = new int[128];
int left=0;
int max=0;
for(int i=0;i<s.length();i++){
left = Math.max(left,lastPosition[s.charAt(i)]);
max = Math.max(max,i-left+1);
lastPosition[s.charAt(i)] = i+1;
}
return max;
}
}