给定一个字符串,找出最长的不具有重复字符的子串的长度。例如,“abcabcbb”不具有重复字符的最长子串是“abc”,长度为3。对于“bbbbb”,最长的不具有重复字符的子串是“b”,长度为1。
class Solution {
public:
int lengthOfLongestSubstring(string s)
{
int len = s.length();
if(len==0) return 0;
int maxLen = 0,left = 0;
unordered_map<char,int> charMap;
for(int i=0;i<len;i++)
{
if(charMap.find(s[i]) != charMap.end())
left = max(left,charMap[s[i]]+1);
maxLen = max(maxLen,i-left+1);
charMap[s[i]] = i;
}
return maxLen;
}
};
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
const int ASCII=26;
int last[ASCII];
int start=0;
fill(last,last+ASCII,-1);
int max_len=0;
for(int i=0;i<s.size();++i)
{
if(last[s[i]-'a']>=start)
{
max_len=max(i-start,max_len);
start=last[s[i]-'a']+1;
}
last[s[i]-'a']=i;
}
return max((int)s.size()-start,max_len);
}
};
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<char , int> strMap;
int num = 0;//最大substring的size,初始化为0
int start = -1;//起始点坐标
for(int i = 0;i<s.size();i++)
{
if(strMap.count(s[i]) != 0)
{
start = max(start,strMap[s[i]]);//删除左边界的无用点
}
strMap[s[i]] = i;
num = max(num,i-start);//计算size
}
return num;
}
};
public class Solution {
/**
* @param s: a string
* @return: an integer
*/
public int lengthOfLongestSubstring(String s) {
// write your code here
int[] cnt = new int[256];
char[] sc = s.toCharArray();
int ans = 0;
for(int l = 0, r = 0; r < sc.length; r++){
cnt[sc[r]]++;
// 找到第一个重复的字符
while(cnt[sc[r]] > 1){
cnt[sc[l]]--; //将前面的字符重置
l++;
}
ans = Math.max(ans, r - l + 1);
}
return ans;
}
}
class Solution {
public int lengthOfLongestSubstring(String s) {
//滑动窗口 思路 维护1个HashSet(window) window装当前窗口的字符统计
if(s.length() == 0){
return 0;
}
if(s.length() == 1){
return 1;
}
int res = 0;
HashSet<Character> window = new HashSet<>();
int l=0;
int r=0;
while(r<s.length()){
char ch = s.charAt(r);
//如果新元素窗口内存在 就需要不断地缩小窗口,直到这个元素不存在
while(l<r && window.contains(ch)){
window.remove(s.charAt(l));
l++;
}
//添加完元素后,就开始统计最大长度
window.add(ch);
res = Math.max(res,r-l+1);
r++;
}
return res;
}
} //可以考虑一下暴力求解
class Solution {
public:
/**
*
* @param s string字符串
* @return int整型
*/
int lengthOfLongestSubstring(string s) {
// write code here
if(s.empty()||s.size()==0)
return 0;
int len = s.length();
int start = -1;
int end = -2;
//遍历所有的可能子串
for(int i = 0;i<len;i++)
{
for(int j = i+1;j<=len;j++)
{
int flag = 1;
//注意substring(i,j)是[i,j),左闭右开
string str = s.substr(i,j-i);
//判断是否存在重复的字符
for(int k = 0; k < str.length();k++)
for(int l = k+1;l<str.length();l++)
{
if(str[l]==str[k])
flag = 0;
}
//当不存在重复的字符
if(flag==1)
{
//判断是不是比当前的串长
if((j-i)>=(end-start))
{
start = i;
end = j;
}
}
}
}
return end-start;
}
}; class Solution {
public:
int lengthOfLongestSubstring(string s) {
// write code here
map<char, int> gone;
int start = 0, maxl = 0, ans = 0;
for(int i=0; i<s.size(); ++i){
auto it = gone.find(s[i]);
if(it == gone.end() || it->second < start)
gone[s[i]] = i, ++maxl;
else{
ans = max(maxl, ans);
maxl -= it->second - start;
start = it->second+1;
it->second = i;
}
}
return max(maxl, ans);
}
}; import java.util.HashSet;
public class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int i = 0;
int j = 0;
int maxLen = 0;
HashSet<Character> set = new HashSet<>();
while (i <= j && j < s.length()) {
if (!set.contains(s.charAt(j))) {
set.add(s.charAt(j));
j++;
maxLen = Math.max(maxLen, j - i);
} else {
set.remove(s.charAt(i));
i++;
}
}
return maxLen;
}
}
/*滑动窗口设计思想:
创建一个ArrayList类型的list,遍历字符串,一个个将字符加入进来,遇到重复的字符,则执行回退操作,然后清空list
进入下一个循环,继续将不重复的字符加入进去。
每次需要记下list的大小,比较得到最长的longest subString的长度
比如字符串“wlrbbmqcmdghy”
窗口变化情况为:“wlrb” -> “bmqc” ->"qcmdghy"
(1)list窗口包含字符串“wlrb”,继续遍历发现重复的字符b,则索引i退回到第一个字符b的位置,即3,清空list
(2)i++,当前索引位置前进一位变为4,即遍历到第二个b字符,从第二个b字符开始遍历,加入不重复的字符
(3)list窗口包含字符串“bmqc”,继续遍历发现重复的字符m,则索引i退回到第一个字符m的索引位置,即5,情况list
(4)i++,索引前进一位,遍历到第字符q字符,从字符q开始遍历,加入不重复的字符
*/
import java.util.ArrayList;
public class Solution {
public int lengthOfLongestSubstring(String s) {
if(s == null || s.length() == 0)
return 0;
int len = s.length();
int longest_len = 0;
ArrayList<Character> list = new ArrayList<>();
for(int i = 0; i < len; i++){
if(!list.contains(s.charAt(i))){
list.add(s.charAt(i));
//每次比较得到最大长度
if(list.size() > longest_len){
longest_len = list.size();
}
}
//回退到重复的字符位置,并清空list
else{
int inner_index = list.indexOf(s.charAt(i));
i = i - (list.size() - inner_index);
list.clear();
}
}
return longest_len;
}
}
public int lengthOfLongestSubstring(String s) {
int count[] = new int[128];
int maxlength = 0;
int start = 0;
for(int i=0; i<s.length(); i++){
char ch = s.charAt(i);
count[(int)ch]++;
if(count[ch]>1){
maxlength = Math.max(maxlength, i - start);
while(s.charAt(start) != ch){
count[s.charAt(start)] --;
start++;
}
count[ch]--;
start++;
}
}
maxlength = Math.max(maxlength, s.length() - start);
return maxlength;
} class Solution {
public:
int lengthOfLongestSubstring(string s) {
int freq[256] = { 0 };//记录是否出现
int l = 0, r = -1;
int res = 0;
while (r+1<s.size())
{
if (freq[s[r + 1]] == 0)//没出现过 标记为出现 后移r
{
freq[s[r + 1]] = 1;
r++;
}
else //出现过 清除l所在位置字符 后移l
{
freq[s[l]] = 0;
l++;
}
res = max(res, r - l + 1);
}
return res;
}
}; class Solution {
public:
int lengthOfLongestSubstring(string s) {
int len = s.length();
int freq[256] = {0};
int i = 0;
int j = -1;
int max_len = 0;
while(i < len){
if(j+1 < len && freq[s[j+1]] == 0){
++freq[s[++j]];
}else{
max_len = max(max_len, j-i+1);
--freq[s[i++]];
}
}
return max_len;
}
};
/*public int lengthOfLongestSubstring(String s) {
if(s==null||s.length()==0) return s.length();
int max=0;
HashMap<Character, Boolean> map =new HashMap<Character,Boolean>();
Queue<Character> queue =new LinkedList<Character>();
for(int i=0;i<s.length();i++){
char ch =s.charAt(i);
if(map.containsKey(ch)){
if(map.get(ch)==true) {//有重复的值
if (queue.peek() ==ch){//第一个重复
queue.poll();
queue.add(ch);
}
else{//除了第一个重复
while(!queue.isEmpty()&&queue.peek()!=ch){//除了那个重复的值
char c= queue.poll();
map.put(c,false);
}
}
}
else{
queue.add(ch);
map.put(ch,true);
max=max<queue.size()?queue.size():max;
}
}
else{
map.put(ch,true);
queue.add(ch);
max=max<queue.size()?queue.size():max;
}
}
return max;
}*/
//参考大牛解法
public int lengthOfLongestSubstring(String s) {
if(s==null||s.length()==0) return s.length();
int left =0,max=0;
HashMap<Character,Integer> map =new HashMap<Character,Integer>();
for(int i=0;i<s.length();i++){
char ch =s.charAt(i);
left = Math.max(left,map.containsKey(ch)?map.get(ch)+1:0);
max =Math.max(max,i-left+1);
map.put(ch,i);
}
return max;
}
这题用暴力时间会超,用这种O(N)时间复杂度,两个指针i,j,i 负责遍历从前往后遍历所有的字符,j 负责滑动到与第i个不重复的位置,这种方式称为“Sliding Window”。import java.util.*;public class Solution {public int lengthOfLongestSubstring(String s) {if(s == null || s.isEmpty()){return 0;}int len = s.length();int i = 0,j = 0,ans = 0;HashSet<Character> set = new HashSet<Character>();while(i < len && j < len){if(!set.contains(s.charAt(j))){set.add(s.charAt(j++));ans = Math.max(ans,j-i);}else{set.remove(s.charAt(i++));}}return ans;}}
/*
* the basic idea is, keep a hashmap which stores the characters in string as keys
* and their positions as values, and keep two pointers which define the max substring.
* move the right pointer to scan through the string , and meanwhile update the hashmap.
* If the character is already in the hashmap,
* then move the left pointer to the right of the same character last found.
* Note that the two pointers can only move forward.
*/
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() < 1)
return 0;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int max = 0;
for (int i = 0,j=0; i < s.length(); i++) {
if(map.containsKey(s.charAt(i))){
j=Math.max(j, map.get(s.charAt(i)+1));
}
map.put(s.charAt(i), i);
max=Math.max(max, i+1-j);
}
return max;
}
/*
* Solution by me Runtime: 51 ms.Your runtime beats 80.99 % of java
* submissions. 思路:确定两个指针p1和p2,再new一个HashSet用来存储subString中的字符
* 循环:p2加1,如果HashSet不含有该字符,subString长度加1;如果含有该字符,把p1指向的字符删除,p1+1
*/
public int lengthOfLongestSubstring_1(String s) {
if (s == null || s.length() < 1)
return 0;
char[] arr = s.toCharArray();
Set<Character> set = new HashSet<Character>();
set.add(arr[0]);
int p1 = 0, p2 = 1;
int tempNum = 1, res = 1;
while (p2 < s.length()) {
while (set.contains(arr[p2])) {
set.remove(arr[p1++]);
tempNum--;
}
set.add(arr[p2++]);
tempNum++;
if (tempNum > res)
res = tempNum;
}
return res;
}
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char,pair<int,int>> map;
if(s.length()==0) return 0;
int max=0x80000000,cur=0;
for(int i=0;i<s.length();i++){
if(map[s[i]].first==0){
map[s[i]].first++;
map[s[i]].second = i;
}
else{
if(cur<=map[s[i]].second){
int lens = i-cur;
cur = map[s[i]].second+1;
if(lens>max) max=lens;
map[s[i]].first++;
map[s[i]].second = i;
}
else{
map[s[i]].first++;
map[s[i]].second = i;
}
}
}
int tmp = (s.length() - cur);
if(tmp>max) max = tmp;
return max;
}
};
/*
尺取法
*/
public class Solution {
public int lengthOfLongestSubstring(String s) {
int head = 0;
int index = 0;
int ans = 0;
int len = s.length();
boolean[] vis = new boolean[256];
for (boolean ele : vis) {
ele = false;
}
while (index < len) {
if (vis[s.charAt(index)] == false) {
vis[s.charAt(index)] = true;
index++;
} else {
ans = Math.max(ans, index - head);
while (s.charAt(head) != s.charAt(index)) {
vis[s.charAt(head)] = false;
head++;
}
head++;
index++;
}
}
return Math.max(ans,len - head);
}
}
// 参考大神的思路,真是学到了!
import java.util.HashMap;
import java.util.Map;
public class Solution {
public int lengthOfLongestSubstring(String s) {
if(s == null || s.length() == 0)
return 0;
// 滑动窗口法计算最长的不重复子串
// map记录字符的index
Map<Character, Integer> map = new HashMap<>();
int leftBound = 0;
int max = 0;
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
leftBound = Math.max(leftBound, map.containsKey(c) ? map.get(c) + 1 : 0);
max = Math.max(max, i - leftBound + 1);
map.put(c, i);
}
return max;
}
}