LeetCode 第三題 無重複字符的最長字串
給定一個字符串,找出不含有重複字符的 最長子串 的長度。
示例:
給定 “abcabcbb” ,沒有重複字符的最長子串是 “abc” ,那麼長度就是3。
給定 “bbbbb” ,最長的子串就是 “b” ,長度是1。
給定 “pwwkew” ,最長子串是 “wke” ,長度是3。請注意答案必須是一個子串,”pwke” 是 子序列 而不是子串。
本文介紹了三種方法,參考地址:[https://leetcode.com/articles/longest-substring-without-repeating-characters/]
方法一:
使用最簡單暴力的方法,將字符串中所有的字串拿出來,在判斷其是否爲無重複的,當然,使用該方法計算超時。
Java
class Solution {
public int lengthOfLongestSubstring(String s) {
int length = 0;
for (int i = 0; i < s.length(); i++) {
for (int j = i + 1; j <= s.length(); j++) { ///注意j的取值範圍
if (allUnique(s, i, j)) {
length = Math.max(length, j - i);
}
}
}
return length;
}
public boolean allUnique(String s, int i, int j) {
HashSet<Character> hashSet = new HashSet<>();
for (int k = i; k < j; k++) {
if (hashSet.contains(s.charAt(k))) {
return false;
} else {
hashSet.add(s.charAt(k));
}
}
return true;
}
}
python
class Solution(object):
def allUnique(self, s, i, j):
my_set = set()
for k in range(i,j):
if s[k] in my_set:
return False
else:
my_set.add(s[k])
return True
def lengthOfLongestSubstring(self,s):
length = 0
for i in range(len(s)):
for j in range(i+1,len(s)+1):
if Solution().allUnique(s, i, j):
length = max(length, j-i)
return length
C++
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int length = 0;
for(int i=0;i<s.length();i++)
{
for(int j=i+1;j<=s.length();j++)
{
if(allUnique(s,i,j))
{
length=max(length,j-i);
}
}
}
return length;
}
bool allUnique(string s, int i, int j)
{
set<char> my_set = set<char>();
for(int k=i; k<j; k++)
{
set<char>::iterator it = my_set.find(s[k]);
if(it!=my_set.end())
{
return false;
}
else
{
my_set.insert(s[k]);
}
}
return true;
}
};
方法二
使用滑動窗口的方式,使用while循環代替方法一中的雙重for循環,代碼效率得到有效提升,更加簡潔。
Java
public int lengthOfLongestSubstring(String s)
{
int length = 0;
int i = 0, j = 0;
HashSet<Character> hashSet = new HashSet<>();
while(i < s.length() && j < s.length())
{
if(!hashSet.contains(s.charAt(j)))
{
hashSet.add(s.charAt(j++));
length = Math.max(length, j-i);
}
else
{
hashSet.remove(s.charAt(i++));
}
}
return length;
}
python
def lengthOfLongestSubstring(self, s):
i = 0; j = 0; length = 0
my_set = set()
while(i < len(s)) and (j < len(s)):
if s[j] in my_set:
my_set.remove(s[i])
i = i+1
else:
my_set.add(s[j])
j = j+1
length = max(length, j-i)
return length
C++
int lengthOfLongestSubstring(string s)
{
set<char> my_set = set<char>();
int i=0,j=0,length=0;
while(i<s.length()&&j<s.length())
{
set<char>::iterator it = my_set.find(s[j]);
if(it==my_set.end())
{
my_set.insert(s[j++]);
length = max(length,j-i);
}
else
{
my_set.erase(s[i++]);
}
}
return length;
}
方法三
更改滑動窗口,使用map,變量i的步長不在是1了,而是根據實際情況而定。
Java
public int lengthOfLongestSubstring(String s)
{
int length = 0;
HashMap<Character, Integer>hashMap = new HashMap<>();
for(int i=0, j =0;j<s.length();j++)
{
if(hashMap.containsKey(s.charAt(j)))
{
i = Math.max(i, hashMap.get(s.charAt(j)));
}
length = Math.max(length, j-i+1);
hashMap.put(s.charAt(j), j+1);
}
return length;
}
python
def lengthOfLongestSubstring(self, s):
length = 0
i = 0
my_map = {}
for j in range(len(s)):
if s[j] in my_map:
i = max(i, my_map[s[j]])
length = max(length, j-i+1)
my_map[s[j]] = j+1
return length
C++
int lengthOfLongestSubstring(string s)
{
int length = 0;
map<char,int> my_map = map<char,int>();
for(int i=0,j=0;j<s.length();j++)
{
map<char,int>::iterator it = my_map.find(s[j]);
if(it!=my_map.end())
{
i = max(i,it->second);
}
length = max(length, j-i+1);
my_map[s[j]]=j+1;
}
return length;
}