xxxxxxxxxx
Longest Substring Without Repeating Characters
Problem Statement
Given a string s, find the length of the longest substring without repeating characters.
Example
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of
3.
Approach: Sliding Window
A common and efficient approach to solve this problem is using the sliding window technique.
Initialize two pointers: left and right to mark the beginning and end of the sliding window respectively.
Maintain a set: to store unique characters encountered in the current window.
Iterate through the string:
If the current character is not in the set, expand the right pointer and add the character to the set.
If the current character is already in the set, it means we have a repeated character. Shrink the left pointer until the repeated character is removed from the window.
Update the maximum length of the substring found so far.
Python Implementation
Python
def lengthOfLongestSubstring(s: str) -> int:
char_set = set()
left = right = 0
max_length = 0
while right < len(s):
if s[right] not in char_set:
char_set.add(s[right])
max_length = max(max_length, right - left + 1)
right += 1
else:
char_set.remove(s[left])
left += 1
return max_length
Use code with caution.
Explanation
The char_set is used to keep track of unique characters in the current window.
The left and right pointers define the sliding window.
The max_length variable keeps track of the maximum length found so far.
We iterate through the string, expanding the window if the character is new, and shrinking it otherwise.
Time and Space Complexity
Time complexity: O(n) where n is the length of the string.
Space complexity: O(n) in the worst case when all characters are unique.
xxxxxxxxxx
/*
Javascript Solution - With Better Performance
Methods used in this algorithm are:
1. Two Pointer Technique
2. Sliding Window Technique
3. Hash Map
Time complexity: O(N)
Space complexity: O(N),
If the string does not contain repeated characters,
then the hash map will contain N characters.
*/
const s = "sdtvtsgh"
const lengthOfLongestSubstring = function(s) {
let max_length = 0
let map = {}
let l = 0
for (let r = 0; r < s.length; r++) {
if (map.hasOwnProperty(s[r])) {
const collision_index = map[s[r]]
if (collision_index >= l) {
l = collision_index + 1
}
delete map[s[collision_index]]
}
if (!map.hasOwnProperty(s[r])) {
map[s[r]] = r
}
if (max_length < (r + 1) - l) {
max_length = (r + 1) - l
}
console.log(map, ': (', r + 1, '-', l, ')')
}
return max_length
}
console.log(lengthOfLongestSubstring(s))
// [Log]:
{ s: 0 } : ( 1 - 0 )
{ s: 0, d: 1 } : ( 2 - 0 )
{ s: 0, d: 1, t: 2 } : ( 3 - 0 )
{ s: 0, d: 1, t: 2, v: 3 } : ( 4 - 0 )
{ s: 0, d: 1, v: 3, t: 4 } : ( 5 - 3 )
{ d: 1, v: 3, t: 4, s: 5 } : ( 6 - 3 )
{ d: 1, v: 3, t: 4, s: 5, g: 6 } : ( 7 - 3 )
{ d: 1, v: 3, t: 4, s: 5, g: 6, h: 7 } : ( 8 - 3 )
max_length = 5
xxxxxxxxxx
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
if (!s.length) return 0
let left = 0, right = 0
let maxLength = -Infinity
const hashSet = {}
const len = s.length
while(right < len){
if (hashSet.hasOwnProperty(s[right])){
if (hashSet[s[right]] >= left){
left = hashSet[s[right]]+1
}
}
const lenn = right-left+1
maxLength = Math.max(lenn, maxLength)
hashSet[s[right]] = right
right++
}
return maxLength
};
xxxxxxxxxx
// JavaScript Solution - Credit to @albertchanged on LC
// Sliding window implementation
var lengthOfLongestSubstring = function(s) {
if (!s.length) return 0;
let left = 0, right = 0;
let maxLength = -Infinity;
const set = new Set();
while (right < s.length) {
// If s[right] has not been seen yet
if (!set.has(s[right])) {
// Add it to the set
set.add(s[right]);
// Increase size of window to right
right++;
// Update maxLength; set size represents length of unique substring
maxLength = Math.max(maxLength, set.size);
} else {
// We've seen s[right] so we need to shrink the window
// Delete s[left] from set
set.delete(s[left]);
// Shrink window from left
left++;
}
}
return maxLength;
}
xxxxxxxxxx
import java.io.*;
class GFG {
public static int longestUniqueSubsttr(String str)
{
String test = "";
// Result
int maxLength = -1;
// Return zero if string is empty
if (str.isEmpty()) {
return 0;
}
// Return one if string length is one
else if (str.length() == 1) {
return 1;
}
for (char c : str.toCharArray()) {
String current = String.valueOf(c);
// If string already contains the character
// Then substring after repeating character
if (test.contains(current)) {
test = test.substring(test.indexOf(current)
+ 1);
}
test = test + String.valueOf(c);
maxLength = Math.max(test.length(), maxLength);
}
return maxLength;
}
// Driver code
public static void main(String[] args)
{
String str = "geeksforgeeks";
System.out.println("The input string is " + str);
int len = longestUniqueSubsttr(str);
System.out.println("The length of the longest "
+ "non-repeating character "
+ "substring is " + len);
}
}
// This code is contributed by Alex Bennet
xxxxxxxxxx
class Solution {
public int lengthOfLongestSubstring(String s) {int max=0;
HashMap<Character,Integer>hm=new HashMap<>();
for(int i=0,j=0;i<s.length();i++){
if(hm.containsKey(s.charAt(i))){
j=Math.max(j,hm.get(s.charAt(i))+1);
}
hm.put(s.charAt(i),i);
max=Math.max(max,i-j+1);
}
return max;
}
}
xxxxxxxxxx
public class Solution
{
public int LengthOfLongestSubstring(string str)
{
var dict = new Dictionary<char, int>();
var max = 0;
int start = 0;
for (int i = 0; i < str.Length; i++)
{
var x = str[i];
if (!dict.ContainsKey(x))
{
dict.Add(x, 1);
}
else
{
dict[x] += 1;
while (start <= i && dict.ContainsKey(str[start]) && dict[x] > 1)
{
dict[str[start]]--;
if (dict[str[start]] == 0)
dict.Remove(str[start]);
start++;
}
}
max = Math.Max(max, i - start + 1);
}
return max;
}
}
xxxxxxxxxx
/*
Given a string s, find the length of the longest substring (A substring is
a contiguous non-empty sequence of characters within a string.)
without repeating characters.
Example 1:
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Example 2:
Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3:
Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and
not a substring.
*/
const longestStr = s => {
if(s.length < 2) return s.length
let [left, right, partial, curIdx, finalLength] =
[0, s.length, new Set(), 0, -Infinity]
while (left < right) {
partial.add(s[left])
const curChar = s[left+1]
// Base case to exit loop early
if (finalLength > (right - curIdx)) break
if (partial.has(curChar)) {
curIdx += 1
left = curIdx
partial.size > finalLength ? finalLength = partial.size : null
partial.clear()
}else left++
left === right ? partial.size > finalLength ?
finalLength = partial.size : null : null
}
return finalLength
}
const s = "abcabcbb" // 3
const res = longestStr(s)
console.log(res)
/*
Time Complexity: O(n) (average case)
Space Complexity: O(n)
*/
// With love @kouqhar
xxxxxxxxxx
class DataDTO {
String? _name;
String? _gender;
int? _age;
Address? _address;
List<PhoneNumber>? _phoneNumber;
DataDTO(
{String? name,
String? gender,
int? age,
Address? address,
List<PhoneNumber>? phoneNumber}) {
if (name != null) {
this._name = name;
}
if (gender != null) {
this._gender = gender;
}
if (age != null) {
this._age = age;
}
if (address != null) {
this._address = address;
}
if (phoneNumber != null) {
this._phoneNumber = phoneNumber;
}
}
String? get name => _name;
set name(String? name) => _name = name;
String? get gender => _gender;
set gender(String? gender) => _gender = gender;
int? get age => _age;
set age(int? age) => _age = age;
Address? get address => _address;
set address(Address? address) => _address = address;
List<PhoneNumber>? get phoneNumber => _phoneNumber;
set phoneNumber(List<PhoneNumber>? phoneNumber) => _phoneNumber = phoneNumber;
DataDTO.fromJson(Map<String, dynamic> json) {
_name = json['name'];
_gender = json['gender'];
_age = json['age'];
_address =
json['address'] != null ? new Address.fromJson(json['address']) : null;
if (json['phoneNumber'] != null) {
_phoneNumber = <PhoneNumber>[];
json['phoneNumber'].forEach((v) {
_phoneNumber!.add(new PhoneNumber.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this._name;
data['gender'] = this._gender;
data['age'] = this._age;
if (this._address != null) {
data['address'] = this._address!.toJson();
}
if (this._phoneNumber != null) {
data['phoneNumber'] = this._phoneNumber!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Address {
String? _street;
String? _city;
String? _state;
String? _postalCode;
Address({String? street, String? city, String? state, String? postalCode}) {
if (street != null) {
this._street = street;
}
if (city != null) {
this._city = city;
}
if (state != null) {
this._state = state;
}
if (postalCode != null) {
this._postalCode = postalCode;
}
}
String? get street => _street;
set street(String? street) => _street = street;
String? get city => _city;
set city(String? city) => _city = city;
String? get state => _state;
set state(String? state) => _state = state;
String? get postalCode => _postalCode;
set postalCode(String? postalCode) => _postalCode = postalCode;
Address.fromJson(Map<String, dynamic> json) {
_street = json['street'];
_city = json['city'];
_state = json['state'];
_postalCode = json['postalCode'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['street'] = this._street;
data['city'] = this._city;
data['state'] = this._state;
data['postalCode'] = this._postalCode;
return data;
}
}
class PhoneNumber {
String? _type;
String? _number;
PhoneNumber({String? type, String? number}) {
if (type != null) {
this._type = type;
}
if (number != null) {
this._number = number;
}
}
String? get type => _type;
set type(String? type) => _type = type;
String? get number => _number;
set number(String? number) => _number = number;
PhoneNumber.fromJson(Map<String, dynamic> json) {
_type = json['type'];
_number = json['number'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['type'] = this._type;
data['number'] = this._number;
return data;
}
}
xxxxxxxxxx
class Autogenerated {
int? id;
int? age;
String? name;
Autogenerated({this.id, this.age, this.name});
Autogenerated.fromJson(Map<String, dynamic> json) {
id = json['id'];
age = json['age'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['age'] = this.age;
data['name'] = this.name;
return data;
}
}
xxxxxxxxxx
class Solution {
/**
* @param String $s
* @return Integer
*/
function lengthOfLongestSubstring($s) {
}
}