Finding the most frequent character in a string javascript - javascript

Assuming I have the following string "355385". I need a simple JavaScript that can tell me that the most mentioned character is 5. Thank you in advance.
I tried with this one but no results.
var exp = '355385' ;
var exps =exp.split("");
var expCounts = { };
for (var i=0;i<exp.length;i++)
{expCounts["_" + exps[i]] = (expCounts["_" + exps[i]] || 0) + 1 ;
if (expCounts==3) exps=exps[i]; }; exps;

This will loop over every character in the string and keep track of each character's count and the character with the maximum count:
var exp = '3553853335' ;
var expCounts = {};
var maxKey = '';
for(var i = 0; i < exp.length; i++)
{
var key = exp[i];
if(!expCounts[key]){
expCounts[key] = 0;
}
expCounts[key]++;
if(maxKey == '' || expCounts[key] > expCounts[maxKey]){
maxKey = key;
}
}
console.debug(maxKey + ":" + expCounts[maxKey]);
Update:
Here is an ES6 version that will handle strings where multiple character have the same max count
function maxCount(input) {
const {max, ...counts} = (input || "").split("").reduce(
(a, c) => {
a[c] = a[c] ? a[c] + 1 : 1;
a.max = a.max < a[c] ? a[c] : a.max;
return a;
},
{ max: 0 }
);
return Object.entries(counts).filter(([k, v]) => v === max);
}
Example (please excuse the crude output):
maxCount('--aaaa1111--').join(' | ').replace(/,/g, ':');
outputs 1:4 | -:4 | a:4

var getMax = function (str) {
var max = 0,
maxChar = '';
str.split('').forEach(function(char){
if(str.split(char).length > max) {
max = str.split(char).length;
maxChar = char;
}
});
return maxChar;
};
logs
getMax('355385') //5;
getMax('35538533') //3;
in equal case it will return first number
getMax('3553') //3;

var string = "355385",
counter = {};
for (var i = 0, len = string.length; i < len; i += 1) {
counter[string[i]] = (counter[string[i]] || 0) + 1;
}
var biggest = -1, number;
for (var key in counter) {
if (counter[key] > biggest) {
biggest = counter[key];
number = key;
}
}
console.log(number);
# 5

var exp = '355385';
var findMostFrequent = function (string) {
var chars = {}, first = string.charAt(0);
chars[first] = 1;
var maxChar = first, maxCount = 1;
for (var i = 1; i < string.length; i++) {
var char = string.charAt(i);
if (chars[char]) {
chars[char]++;
} else {
chars[char] = 1;
}
if (chars[char] > maxCount) {
maxChar = char;
}
}
return maxChar;
};

Another Solution
function maxChar(str) {
const charMap = {};
let max = 0;
let maxChar = '';
for(let char of str){
if(charMap[char]){
charMap[char]++;
}else{
charMap[char] = 1;
}
}
for(let char in charMap){
if(charMap[char] > max){
max = charMap[char];
maxChar = char;
}
}
return maxChar;
}
Result:
maxChar('355385')
"5"

Another way to get the most frequent character in a string - sort frequency map into an array and then return the first (greatest) value from that array:
function highest (string) {
let array = Array.from(string);
let frequencyMap = {};
array.forEach((value, index) => {
if (!frequencyMap[value]) {
frequencyMap[value] = 0;
}
frequencyMap[value] += 1;
})
let frequencyArray = Object.entries(frequencyMap);
frequencyArray.sort((a, b) => {
if (a[1] < b[1]) {
return 1;
}
if (a[1] > b[1]) {
return -1;
}
return 0;
});
return(frequencyArray[0][0]);
}
console.log(highest("hello World"));
returns "l"

None of the answers above take into consideration that JavaScript internally uses UTF-16
const s = "πŸ˜„πŸ˜…πŸ˜„πŸ˜„πŸ˜…πŸ˜…πŸ˜„πŸ˜„πŸ˜±πŸ˜±πŸ˜„";
function getMostFrequentChar(s) {
const len = s.length;
const freq = {};
let maxFreq = 0;
let maxChar;
for (let i = 0; i < len; ++i) {
const isPair = (s.charCodeAt(i) & 0xF800) == 0xD800;
const c = isPair ? s.substr(i++, 2) : s[i];
const f = (freq[c] || 0) + 1;
freq[c] = f;
if (f > maxFreq) {
maxFreq = f;
maxChar = c;
}
}
return {maxFreq, maxChar, freq}
}
console.log(getMostFrequentChar(s));
Note: the code above assumes the string is valid UTF-16. It's possible to construct a string that is not valid UTF-16 in which case maybe you could change isPair to
const isPair = len - i > 1 &&
s.charCodeAt(i ) & 0xF800) == 0xD800 &&
s.charCodeAt(i + 1) & 0xF800) == 0xD800;
But it's not clear what a character with an invalid UTF-16 value means.
It also won't handle more funky unicode
s = "πŸ‘¦πŸΏπŸ‘¦πŸ‘¦πŸΏπŸ‘¦πŸ‘¦πŸ»πŸ‘¦πŸ½πŸ‘¦πŸΎπŸ‘¦πŸΏ"
There are many graphmemes that take multiple unicode code points
Also, splitting the string using split is SSSSSSLLLLLOOOOWWWW and a huge memory hog if the string is long.

Here is yet another answer to this question:
For this I have considered that the character can be of whatevert kind except a space
function findHighestFreqInString(str) {
if (!str) return null
let cleanedStr = str.replace(/\s/g, '') //assumes no spaces needed
if (cleanedStr.length === 0) return null
let strObj = {}
let topChar = ''
for (let val of cleanedStr) {
strObj[val] = (strObj[val] || 0) + 1
if (topChar === '' || strObj[val] >= strObj[topChar]) topChar = val
}
return topChar
}
Here is how you would use it:
findHighestFreqInString('my name is Someone') // returns: e
findHighestFreqInString('') // returns: Null
findHighestFreqInString(' ') // returns: Null

Here is:
let str = '355385';
function mostFrequentCharacter(str) {
let charactersArr = str.split(''),
bins = {};
charactersArr.map(el => bins[el] = (bins[el] || 0) + 1);
return Object.keys(bins).map(key => ({
name: key,
count: bins[key]
})).sort((a, b) => b.count - a.count)[0];
}

You can use the following solution to find the most frequent character in a string:
function getMostRepeatedCharacter(string) {
return string.split('').reduce((acc,char)=>{
let len = string.split(char).length - 1;
return len > acc[1] ? [char,len] : acc
},['',0])[0]
}
getMostRepeatedCharacter('wediuaududddd') // d

Want to share this ES6 functional approach. Please provide your input.
function maxChar(myStr) {
let charObj = {};
return [...myStr].reduce((_, char) => {
if (char in charObj) charObj[char]++;
else if (char !== " ") charObj[char] = 1;
return Object.keys(charObj).reduce((a, b) => {
return charObj[a] > charObj[b] ? a : b;
});
});
}

The simplest approach will be like this:
function maxChar(str) {
const charMap = {};
let max = 0;
let maxChar = '';
start by making an object of words and how many they repeated, to do that we have to loop through the string using for of and implementing the conditions:
for (let char of str) {
if (charMap[char]) {
charMap[char]++;
} else {
charMap[char] = 1;
}
}
and now loop through the object using for in
for (let char in charMap) {
if (charMap[char] > max) {
max = charMap[char];
maxChar = char;
}
}
return maxChar;
}

this is another (bizarre) way
It substitute the current character with blank for check how many times is present in the string making the difference of length with original pattern
var str = "355385";
var mostLength = 0;
var characterMostLength;
for(t = 0; t< 10; t++)
{
var res = str.length - str.replace(new RegExp(t, "g"), "").length;
if (res > mostLength){
characterMostLength = t;
mostLength = res;
}
}

function solution(N) {
var textToArr = N.split('');
var newObj = {};
var newArr = [];
textToArr.map((letter) => {
if(letter in newObj){
newObj[letter] = newObj[letter]+1;
} else {
if(letter !== ' '){
newObj = Object.assign(newObj, {[letter]: 1})
}
}
});
for(let i in newObj){
newArr.push({name: i, value: newObj[i]})
}
var res = newArr.sort((a,b) => b.value-a.value)[0];
return res.name+':'+res.value
}
solution("hello world");

this is a simple Idea that only includes one pass-through with a hashmap. The only thing this does not do is handle several max numbers. I really hope you enjoy my solution :) .
function maxChar(str) {
//Create the output and the hashmap
let m = {}, ans
//Loop through the str for each character
//Use reduce array helper because of the accumulator
str.split('').reduce((a, c) => {
//Increments Map at location c(character) unless it does not already exist
m[c] = m[c] + 1|| 1
//This checks to see if the current passthrough of m[c] is greater than or equal to the accumulator, if it is, set the answer equal to the current character. If it's not keep the ans the same.
ans = m[c] >= a ? c : ans
//Only increment the accumulator if Map at location c(character) is greater than the accumulator. Make sure to return it otherwise it won't increment.
return a = m[c] > a ? a + 1 : a
}, 1)
//Lastly return the answer
return ans
}

Simplest way to find maximum number of occurring character in string
var arr = "5255522322";
var freq:any = {};
var num;
for(let i=0;i<arr.length;i++) {
num = arr[i];
freq[num] = freq[num] >= 1 ? freq[num] + 1 : 1;
}
var sortable:any = [];
for(let i in freq)
{
sortable.push(i);
}
var max = freq[sortable[0]];
var data:any = "";
var value = sortable[0];
for(let i=0;i<sortable.length;i++) {
if(max > freq[sortable[i]]){
data = "key" + value + " " + "value" + max;
}else{
value = sortable[i]
max = freq[sortable[i]];
}
}
console.log(data);

function maxChara(string) {
charMap = {};
maxNum = 0;
maxChar = "";
string.toString().split("").forEach(item => {
if (charMap[item]) {
charMap[item]++;
} else {
charMap[item] = 1;
}
});
for (let char in charMap) {
if (charMap[char] > maxNum) {
maxNum = charMap[char];
maxChar = char;
}
}
return maxChar;
}
let result = maxChara(355385);
console.log(result);

Here str will the string that needs to be verified.
function maxCharacter(str){
let str1 = str; let reptCharsCount=0; let ele='';let maxCount=0;
let charArr = str1.split('');
for(let i=0; i< str1.length; i++){
reptCharsCount=0;
for(let j=0; j< str1.length; j++){
if(str1[i] === str1[j]) {
reptCharsCount++;
}
}
if(reptCharsCount > maxCount) {
ele = str1[i];
maxCount = reptCharsCount;
}
}
return ele;
}
input
maxCharacter('asdefdfdsdfseddssdfsdnknmwlqweeeeeeeesssssssssssseeee');
output
"s"

function freq(str) {
var freqObj = {};
str.forEach((item) => {
if (freqObj[item]) {
freqObj[item]++;
}
else {
freqObj[item] = 1;
}
});
return freqObj;
}
function findmaxstr(str) {
let max = 0,res,freqObj;
freqObj = freq(str.split(""));
for(let keys in freqObj){
if (freqObj[keys] > max) {
max = freqObj[keys];
res = keys;
}
}
console.log(res);
return res;
}
findmaxstr("javasdasdsssssscript");

const maxChar = (str) => {
let obj = {};
for (let char of str) {
(!obj[char]) ? obj[char] = 1: obj[char]++;
}
maxCharcount = Math.max(...Object.values(obj));
const key = Object.keys(obj).filter(key => obj[key] === maxCharcount);
console.log(`Most repeated character/characters in the given string "${str}" is/are given below which repeated ${maxCharcount} times`);
console.log(...key);
}
maxChar("355385");

Here is the code, where it also checks for lower and upperCase characters with the same max count and returns a Lower ASCII character as a Max.
function mostFrequent(text) {
let charObj={}
for(let char of text){
if(char!==' '){
if(charObj.hasOwnProperty(char)) charObj[char]=charObj[char]+1;
else charObj[char]= 1
}
}
let maxOccurance= Object.keys(charObj)[0], i=0;
for(let property in charObj){
if(i>0){
if(charObj[property]> charObj[maxOccurance])
maxOccurance= property
else if(charObj[property]=== charObj[maxOccurance])
{
if(property<maxOccurance)
maxOccurance=property
}
}
i++
}
return [maxOccurance, charObj[maxOccurance]]
}

let str = '355385';
let max = 0;
let char = '';
str.split('').forEach((item) => {
let current = str.split(item).length;
if (current > max) {
max = current;
char = item;
}
});
console.log(char + ' occurred ' + (max - 1) + ' times');

var exp = '35585' ;
var expCounts = { };
let maxChar = ''
let count = 0
for(let i = 0; i < exp.length; i++){
let char = exp[i]
expCounts[char] = expCounts[char] + 1 || 1
if(expCounts[char] > count){
maxChar = char
count = expCounts[char]
}
console.log(maxChar)
}

function checkNoofOccurenance(string) {
const arr = [...new Set(string.split(''))].sort();
const finalObj = {};
arr.forEach((item) => {
finalObj[item] = string.split(item).length - 1;
});
const item=Object.keys(finalObj).reduce((occ, toBeComapir)=>finalObj[occ]>finalObj[toBeComapir]?occ:toBeComapir)
return item;
}

Using Hasmaps we can find the most frequent char and occurrence all in O(N) time complexity. Below is the code. I have used one hasmap to save all the values and while i am doing it, i am also calculating the max occurrence and the max char.
var mostFreq = function(s) {
let myMap = new Map();
let temp;
let counter = 0;
let mostFrequentChar;
for(let i =0;i <s.length;i++){
if(myMap.has(s.charAt(i))){
temp = myMap.get(s.charAt(i));
temp = temp + 1;
myMap.delete(s.charAt(i));
myMap.set(s.charAt(i) , temp)
if(temp > counter){
counter = temp;
mostFrequentChar = s.charAt(i);
}
}else{
myMap.set(s.charAt(i), 1)
}
}
//if you want number of occerance of most frequent char = counter
//if you want list of each individual char and its occurrence = myMap
//if you just want the char that is most frequence = mostFrequentChar;
return mostFrequentChar;
};

If you want the count of the letter as well, You can do this
const { letter, count } = input.split("").reduce(
(acc, letter) => {
const count = input.split(letter).length - 1;
return count > acc.count
? { letter, count }
: { letter: acc.letter, count: acc.count };
},
{ letter: "", count: 0 }
);
Here We are splitting the string, applying a reduce to the result. The Reduce Counts how many instances of a character are there in a string, using input.split(letter).length - 1; And if the count is greater than the previous count, updates the accumulated value to be the current value

let string = "355385";
function printFirstRepeat(str){
let output= {};
for (let char of str) {
char = char.toLowerCase();
output[char] = ++output[char] || 1;
if(output[char] > 1) return char;
}
return "Not Found"
}
console.log(printFirstRepeat(string));

Algorithm: Find maximum occurring character in a string (time complex: O(N))
I'll provide my solution to this algo-problem by utilizing the most recent concepts of javascript
const getMaxCharacter = (str) => {
let max = 0;
let maxChar = '';
str.split('').forEach((char) => {
if (str.split(char).length > max) {
max = str.split(char).length - 1;
maxChar = char;
}
});
return `The max letter is : ${maxChar} and the max number of times it is seen is: ${max} times`;
};
Let's express an easy way of testing the function logic I wrote it:
const letter = 'Hello Student';
getMaxCharacter(letter);
In the function developed, I've used the concepts below:
Arrow Function
Anonymous Funciton
Declare property by using let/const
Template Literals
forEach(); (array helper) & split()

This is simple and optimized solution and it returns the first occurring char if there are chars equals in counts
function maxOccurance(str) {
let maxOccurringChar = "";
const charMap = {};
for (let index = 0; index < str.length; index++) {
const ele = str.charAt(index);
if (!charMap[ele]) {
charMap[ele] = {
startIndex: index,
value: 1
};
} else {
charMap[ele].value = charMap[ele].value + 1;
}
if (
!maxOccurringChar ||
charMap[maxOccurringChar].value < charMap[ele].value
) {
maxOccurringChar = ele;
} else if (
charMap[maxOccurringChar].value === charMap[ele].value &&
charMap[ele].startIndex < charMap[maxOccurringChar].startIndex
) {
maxOccurringChar = ele;
}
}
return maxOccurringChar;
}
console.log( maxOccurance("bacdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")
);

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
<p id = "myString">Hello World! I am Julio!</p>
<p id = "mRCharacter"></p>
<script>
var string = document.getElementById("myString").innerHTML;
var mRCharater = mostRepetedCharacter(string);
document.getElementById("mRCharacter").innerHTML = mRCharater;
console.log(mRCharater);
function mostRepetedCharacter(string){
var mRCharater = "";
var strLength = string.length;
var i = 0;
var count = 0;
var max = 0;
var rest = strLength - 1;
while (i < strLength){
var j = i + 1;
while (j <= rest){
if (string[i] === string[j]){
count++;
}
if (count > max){
max = count;
mRCharater = string[i];
}
j++;
}
i++;
count = 0;
}
return mRCharater;
}
</script>
</body>
</html>
enter code here

Related

Reverse string without reversing special characters using Javascript

I am unable to find problem in this code. I want to reverse the string without reversing special characters. So, if the string is 'ab#$cd!' ,the output would be 'dc#$ba!' the output I am getting is 'ab#$cd!' (the same as input).
Kindly find the problem in the code.
function isAlphabet(x) {
if ((x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z')) {
return true
} else {
return false
}
}
function reverse() {
var string1 = [];
string1 = 'ab#$cd!'
var n = string1.length;
var r = n - 1;
var i = 0;
while (i < r) {
if (!isAlphabet(string1[i])) {
i++;
} else if (!isAlphabet(string1[r])) {
r--;
} else {
var temp;
temp = string1[i];
string1[i] = string1[r];
string1[r] = temp;
i++;
r--;
}
}
return string1;
}
console.log(reverse());
You can't modify string in this way, strings are immutable in JavaScript
var str = "abcdef";
console.log(str[1])
str[1] = "x"
console.log(str)
Change your string to array, modify array and then join it:
var str = "abcdef", arr = str.split("");
console.log(arr[1])
arr[1] = "x"
console.log(arr.join(""))
Your example (consider renaming variables - I left original names):
function isAlphabet(x) {
if ((x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z')) {
return true
} else {
return false
}
}
function reverse() {
var string1 = [];
string1 = 'ab#$cd!'.split("")
var n = string1.length;
var r = n - 1;
var i = 0;
while (i < r) {
if (!isAlphabet(string1[i])) {
i++;
} else if (!isAlphabet(string1[r])) {
r--;
} else {
var temp;
temp = string1[i];
string1[i] = string1[r];
string1[r] = temp;
i++;
r--;
}
}
return string1.join("");
}
console.log(reverse());
Here is a snippit that uses split(), pop(), push() & reverse() methods.
function reverseString(str){
var splitString, exclamationMark, reverseArray, joinArray;
splitString = str.split("");
exclamationMark = splitString.pop();
reverseArray = splitString.reverse();
reverseArray.push(exclamationMark);
joinArray = reverseArray.join("");
return joinArray;
}
console.log(reverseString("ab#$cd!"));
var str = "#hello$worl!d" var spclindx = []; var final = ''
var onlyalpha = str.match(/[a-z]|[A-Z]/g).reverse();
[...str].map((x, key) => { if (!x.match(/[a-z]/i)) { spclindx.push(key + '.' + x) } })
spclindx.map(y => { var sp = y.split('.'); console.log(sp) final = onlyalpha.splice(sp[0], 0, sp[1]) final = onlyalpha.join('') })
console.log(final)

how to get common substring in two string to maintain order?

I am trying to do one problem of hackerrank but I am not able to solve that problem
Can someone please help me with wrong logic implementation done by me?
problem
Print the length of the longest string, such that is a child of both s1 and s2.
Sample Input
HARRY
SALLY
Sample Output
2
Explanation
The longest string that can be formed by deleting zero or more characters from HARRY and SALLY is AY, whose length is 2.
Sample Input 1
AA
BB
Sample Output 1
0
Explanation 1
AA and BB have no characters in common and hence the output is 0
Sample Input 2
SHINCHAN
NOHARAAA
Sample Output 2
3
Explanation 2
The longest string that can be formed between SHINCHAN and NOHARAAA while maintaining the order is NHA.
I have written some logic which is as follows:
function commonChild(s1, s2) {
var arr = s2.split(),
currenString = '',
maxLength = 0,
index = -1;
console.log(arr);
for (var i = 0; i < s1.length; i++) {
var char = s1.charAt(i),
charIndex = arr.indexOf(char);
console.log(char)
if (index < charIndex) {
index = charIndex;
currenString +=char;
}
maxLength= Math.max(maxLength,currenString.length)
}
return maxLength;
}
commonChild('ABCDEF', 'FBDAMN');
console.log(commonChild('ABCDEF', 'FBDAMN'));
pardon me. this is an unoptimized solution.
function maxCommon(a, b, offset) {
offset = offset || 0;
if (a === b) {
return [[a, b]];
}
var possibleSolns = [];
for (var i = 0 + offset; i < a.length; i++) {
for (var j = 0 + offset; j < b.length; j++) {
if (a.charAt(i) === b.charAt(j)) {
possibleSolns.push([
a.substring(0, offset) + a.substring(i),
b.substring(0, offset) +b.substring(j)
]);
break;
}
}
}
var results = [];
possibleSolns.forEach(function(soln) {
var s = maxCommon(soln[0], soln[1], offset+1);
if (s.length === 0) {
s = [[soln[0].substring(0, offset +1), soln[1].substring(0, offset +1)]];
}
results = results.concat(s);
});
return results;
}
var maxLen = -1;
var soln = null;
maxCommon("ABCDEF", "FBDAMN").map(function(_) {
return _[0];
}).forEach(function(_) {
if (_.length > maxLen) {
soln = _;
maxLen = _.length;
}
});
console.log(soln);
I kept most of your logic in the answer:
function commonChild(s1, s2) {
var // Sets strings to arrays
arrayString1 = s1.split(""),
arrayString2 = s2.split(""),
collectedChars = "",
maxLength = 0,
max = arrayString1.length;
for (var i = 0; i < max; i++) {
var
char = arrayString1[i],
count = arrayString2.indexOf(char);
// check if char is in second string and not in collected
if (count != -1 && collectedChars.indexOf(char) == -1) {
collectedChars += char;
maxLength++;
}
}
return maxLength;
}
// expected output 4
console.log(commonChild(
'ABCDEF',
'FBDAMN'
));
// expected output 1
console.log(commonChild(
'AA',
'FBDAMN'
));
Using lodash and spread operation you can do it in this way.
const test = (first, second) => {
const stringArray1 = [...first];
const stringArray2 = [...second];
return _.intersection(stringArray1, stringArray2).length;
}
console.log(test('ABCDEF', 'FBDAMN'));
You can solve it using lcs least common subsequence
function LCS(s1,s2,x,y){
var result = 0;
if(x==0 || y==0){
result = 0
}else if(s1[x-1] == s2[y-1]){
result = 1+ LCS(s1,s2,x-1,y-1)
} else if(s1[x-1] != s2[y-1]){
result = Math.max(LCS(s1,s2,x-1,y), LCS(s1,s2,x,y-1))
}
return result;
}
// Complete the commonChild function below.
function commonChild(s1, s2) {
return LCS(s1,s2,s1.length,s2.length);
}
Based on your code before the edit.
One little change is to change var arr = s2.split() to split('').
The main change in the logic is that I added a loop to run over the string each time from another character (first loop from the first, second from the second etc).
function commonChild(s1, s2) {
var arr = s2.split(''),
currenString = '',
maxLength = 0,
index = -1,
j = -1;
for (var ii = 0; ii < s1.length; ii++) {
index = -1;
currenString = '';
for (var i = ii; i < s1.length; i++) {
var char = s1.charAt(i),
j = arr.indexOf(char);
if (index < j) {
index = j;
currenString += char;
}
maxLength = Math.max(maxLength, currenString.length)
}
}
return maxLength;
}
console.log(commonChild('ABCDEF', 'FBDAMN'));

JS - getting the longest non-repeating character substring from a string

I am trying to solve a task on the leetcode site. My approach to solving this problem was to iterate over a string, and then fill first one array until I find a repeating character, and then start filling another array, until I find a repeating character there as well. Once I would have two filled arrays, I would compare them and keep the longer one, until I am done with iteration. But with these approach I end up checking a lot of things and not sure what to do when I have the secondArray filled and I am still doing the subiteration, to avoid filling the firstArray as well.
In general this code is to cumbersome, and I am not sure anymore how should I solve this?
s = "anviaj"
s = "eeydgwdykpv"
var lengthOfLongestSubstring = function(s) {
let firstArray = [];
let secondArray = [];
let firstArrayFull = false;
let secondArrayFull = false;
let subIterationFinished = false;
if (s.length == 1)
return s;
for (var i = 0; i < s.length -1; i++) {
if (!firstArrayFull) {
firstArray.push(s.charAt(i));
} else if (!secondArrayFull) { secondArray.push(s.charAt(i)); }
for (let j = i + 1; j < s.length; j++) {
if (j + 1 == s.length) {
subIterationFinished = true;
checkArrays();
}
if (!firstArrayFull && !firstArray.includes(s.charAt(j))) {
if (secondArrayFull && !subIterationFinished) {
firstArray = firstArray;
} else {
firstArray.push(s.charAt(j));
}
} else {
firstArrayFull = true;
if (secondArrayFull) {
checkArrays();
}
}
if (firstArrayFull && secondArray.length != 0 && secondArray.includes(s.charAt(j))) {
secondArrayFull = true;
checkArrays();
}
if (firstArrayFull && secondArray.length != 0 && !secondArray.includes(s.charAt(j))) {
secondArray.push(s.charAt(j));
}
}
}
function checkArrays() {
if (secondArray.length > firstArray.length) {
firstArray = [];
firstArrayFull = false;
secondArrayFull = true;
} else {
secondArray = [];
secondArrayFull = false;
firstArrayFull = true;
}
}
return secondArray.length > firstArray.length ? secondArray : firstArray;
};
console.log(lengthOfLongestSubstring(s));
This is a valid, O(n) solution which only constructs the final string once, tested against a 20.000 length string (it should be still fast with a million characters, but stackoverflow limits input to 30K characters).
/**
* #param {string} s
* #return {number}
*/
var lengthOfLongestSubstring = function(s) {
var l = 0;
var r = 0;
var maxL = 0;
var maxR = 0;
var length = () => r - l;
var maxLength = () => maxR - maxL;
var keys = {};
while (r < s.length) {
if (s[r] in keys) {
var newL = keys[s[r]] + 1;
for (var i = l; i < newL; i++) {
delete keys[s[i]];
}
if (maxLength() < length()) {
maxL = l;
maxR = r;
}
l = newL;
}
keys[s[r]] = r;
r = r + 1;
}
if (maxLength() < length()) {
maxL = l;
maxR = r;
}
return maxLength();
};
console.log(lengthOfLongestSubstring("2sLbj8wBPPa5RYgNNwzuYQ7Pz3IehWrxOPiAxbGTw1wpEKyPnWLEuiEiW8vPFGENfjICBeNBeslmT8UZZD7AyUp1WKrC8OneS7GzfacqpzzGB4awH4O7CosGQp3fe3UYTqPT44hHtYfGTLKaZkIt6dA1XQQCzvUYCQFFEGWxzPDFZt2D7a8XT4UEuBrUYo4ml4xds7cQflVD8Hyr9bJcCfC6BeUutQb4SrqUR3SlLNVMVlXEYsHLKbXjl0zYNFeIatfvx5w7UNEfLGqhtzNvGKVixQQ6OIIH835jo7IYp6G7FumW9asgKSjbbEQhfWKenep8yL3psmb1eUl2vWGxDKo8Z82UB4M5LcZ4o2W9nGHrpAkyOdJb6WIc3sfeThMAUHA7Ykh9bNmDrmW7J44eJ1XLbrN6xHnUC8LrGXYlFCh7x1bkjyy08Z7LVQGhnuDU1ZaovmKoTrtgPzvIEESakLXxB2t0RbrTVrnGcstUKtTyHqj8X6e3V0lqHjzGZ0Hpucp0cuJLSHOF4GTnju6JK74EbjN5Di9gy7qbe7K59mjdzlzsGHMRq9POl86bFUOgxyFmHWrPRkQXC1TS5YCUiy1Bbu6MXTLvbL3YnKhyLSWh3lplRlPmkEIYVvgDrUa40n9qNFSdMJya4zH3JJ6J2k5ni4hjlg2IIbpG8FbiTqt24jbFbZQOAhG1DAi7VmySqpaaGiKVmpsVc0iaxGiL1mItDaZlRFox7LgJDmgQJbk7reHfq8FH1uLLSy1py5cyt0QlQwkjZrQAYjbKK3fCSLEMCmDQkhcVOoGpg6YaU7wvoroY4rH1IrB03R0WanRjWKPdGmARZaENOMf9MjfZjonrcaJQDqYUsps4G4i4BDcDq2Jdyg5K9MRa95RMxBqgXQAfdU7wm0uNilaKlBfZY6zxbF2ISW0VDIMY0G5BMvvRr9BmBcDNWoSMhJCpzCjeVmBtcih8gxfw0AAjBhHYdGBzfJk5nytl157onDsHRuXLrDKv0suL9JEsspfIuNZQbMPcS3DQTQPEgNzxpn5e2HPacCc3kKt7sSKvuWwBNuk5CrQMWbkw0EN2mSVrTGNkiqKuMIbYC66e5Rkf287TtxOziCYZ9OpO7gXggr0mYxtXIP8W9thSdnbLOxfSgIAI7IypDXsuQBHnHzAp9O6n5qxhf5lOkPlQARQFsf0YGSTB17JfJ4oV6deCnpahvu3cbZ9yaVfzxwVMfnakqfqRVYCP4SM62Io7X9m4V5Zi7rQZK6aflIuBcLId3wnfZrGQhJzo8S4hixlLY6V2geAWXQkGCjBEb4QoFSRuKkFB7os2WeTssT1Nwipg9U86MH4653htRlyMvSGcFeMks3cOB0mpaDEl2xTqXiDVONhySiyS0SSNRLbbfODYF7jkhRPkUhHM1OaAYPsv9yFo2nLoklfoQheNpGJ1FoEzmAhoa1m9RML57x4kMXRTqj9IwJORHVbWhrl68PKG5JCaA62T03T2amxXAjMritTk8mKeIBz9Dp7UESE5reQR54CIgURceVB5HUfICVcvLvhaAFjEAPOOyC6gQm2es6J3eP5wSkIRYtVHJmk5JzLX9Gk2hCpQBJw8Arv4aRmahh2wFGfHsc7UCqtDBFVXHnO0x5bln6bvltc7vDUl055R1p0LUNq0snysbzlUmRBQYZOAtzwNdX5nOAB10Hp3x2aq71H8wBzDjftckNEahaOdEy8Uh9kxt0T45P6stcJchkmw2oFxOgXfV5NgJD8PgSHZsvNb5xQzV03wtmI0z4gJywBcp0MUjaDcxKwxPr3aj2ytcN1iNH8iKzZwrVnIGREC6icIHP8UYsX7UivMfDOK5SNimTRLoQIOHaF1uurMvc5pDfJjyQUDqU3yocY8Y41sh9F7Cb7n3JfPdtryqMmMCZ7wGZrZjjn2D5icfKW6VOtYtx7PzcbP1KnAr7IP9U1MYUudkJtb46BLjXPUMJ643RBMD2jDh0CqaqqTixoRMPck8YjlT3ZrYSjdyaTpYrb2bPVqev9JE9XeUQdeRa5TqSwVCtMM2rVLQqtYWuopTiX4HnINOQ0gzgymeIk6tqTskaOO38HXdJLxeLgI63XBsIZSPxQeR4oYDrYsvJqY4mcxoDG68iYmE5GhZ9Y701crPacrDH43LrmmJEtPjAwdJQ5d0jxqrsztrow0AnVAQj0U2oLCg08V8LY5tOu5xcs2UxfdYGz1BYmI0vkMBWAlj9oCM776ANNU9f5RY5txfUtd0rhBTj8VtR4H9FiIk34qIC8UCdHaLQYFkSjpFN5bmCjsjxGpEIqksRI2RVOnhm8P3p7rCbeUEidoZ9GcfCUhOqCNg8xJzPLVd37P8TDFej0qRc21d6pR89XsVSAbA5lrzeCjBdfHwi6jkwu47aB8cYC2yED8JqjpGeFymcdW1YifVc9BwP0SUIpmyl0S6VwDMJGGbk81zfVe8tg9arP1SdJGXhb3SdYWaE5u9ejyHoikBkYz0tlZ3idhGT45Iht9tVf8pQ7sTOzfOvWhYciUZE7lYbkqWtz5nJfyTnhMgsFCIDz31WVgimg9xLCRwlSD1MS3zeJpATaaLecvxPtZzMWvnecMgAAoVoxp3JI5SmeQeotlzHuy7LNXDEZeBRwd2IBIXzXH164HEVJsrNWZvlWleYfikx8QnqP1D8o6xgKT1yz3wC5qi8hU7Z8ElXgCxrpoiZM9jI8DWPLq7ImAnTlrkrxCu29jQO4y6VxHcTZjTOLU9e9rwMdhAcoKFGBuS1y6eFyzoSyeL7oQCF5gHuKq731R7PxbWtwyy49xg1hFg5Ao5JimQC0A4h6F4KDdjcEkuXfIdXFla7SCMerJa5UutkOwSF9dSX4OLySG4FAY5nBCb8RRJay8CUmyVpPaXwAVZLOhgrepDFzahn5XAlknBNkzJV6XI9LBNblir2RN0CizYOrIf2Gf64eO9PG72dMfgtQFiirmUOuL1p3m31RymCay1F5zm1rdryluSSFmICpNj0Ecai35ICCpiHf8hXcyCdbY6XIoAGqtWjVs9Mp8WcxShhnh3aWd7Muiuk0PHrd8D9AEPvzz1YOhRxxeW10pGCd1m3c674qn1qYru4W9hqitrZewxJsCdJnymma9UXQF9iZgAcZxVJ8PhoZhjrw6nGAAJaA6PGWiVMjY2qFQUcJ1EPYp6YhnvSADdaWShoWElB59oayNqeoRgG1F4L7EyeuWUntqj9K5sXv9QrHsMQwRF1GDEl1g5DxCO3SDYgNGbi2X7097juv7977UbvWrR5wwl1k40WRH9vhB5Kbvq8ENTsrlK1yBVHVZs9rDtqFSfeLpx9rK4i0WEyB0qp22alJPACaEhNZSpTWdale6cCukfzhPQ7hFZB4cXHvbs4NjLySDUEWU8CveFaapJi1IoSdsjxhbWAD7fIcuNtxVakr2qjKya7HlC2gmIMclvrvf0QVt2wOc5keWNB0sxEjtOJ5CHk7klDiyhUz834Dt9ZbN9HO7EhODNqCIGU7E27GqkLqqdweQBgORjTujvnREza5b73Z6N9PjaiWuXizGUleV8IUUjK4nmRolT1yC1LXsWR3DHd76FLcUBBNgA9zRKfP1xv0X31XG5omELujZLGPhz4UGucP4xgYtlvczb2G4HLPfW7ITH7nCrKKJLTcT8CH9YnwHvtmfBY9r0hFTqJQrwxK23upvLEDf85rLikcoY2YYUqlqIlEpX4o8D3LQ1YqAnlUyMeea9BrHg89yEFtlDhwN6QQI6nKBzV0BFXafZu8TfYLMNW1SfjBwMDGCGe3xsyXPhor72UydZve4KtcXkgxPri1iW4hJvll1JqzKZ5DYkuXSg8HP4X8x8LIiQIGV2fFXtW1NQiC1oXhmXO57shpYuwb9iqmZhRwABGLdEQgzL0deEpMbeQyIkUaXkFSsyCkFQ918fQk5Mtw9aiIm0VVpiRgy648VDInBhIFO2puRIOSRzKIoKfWyh0M6IKKkl0LltXq5ZHAcNVWraPA2Ltx4xYuoC7RayMnmsOgcEpCnKwM47kW6p1Xy0QF2qxRGIhrylhJ1JA6aaGy9BSG6KxaruvmM9WT3ECRZwu0ERr0aglgm2vZFBRXD0T8BJ5bNaWcyIiwckDrw2LDo5zc8BLJ990XgEhgO9R0Ucf2Uuj3CpoJX78RZmLxtFrH6g72YaXMHnBcDPIrRHP1ryWrKwZj57NEWt5W4RXUx92mHXe8uUVRlCAneBUnPPUuIPwOOo9md4HU6q5v4x8mIkBbNsbny0tXa1mIlMO8bjTXZ4friAnWGxgTWwnNnmduNvGTtF7eSY4SuqrKgEbOTUaLJgHcLsm7AxL1jLMfvqmaAxYAKEsjGS0bi1PSh1LSDx17mRCEcmD72knvp4xN5mCMFnxbRF9Ayvd4qCAkx0FT6Eb7EwqpQCfDvAucjzMCTm6FeGOqRJ1XSjVlJcBccHnp7bg9srrPDMjgJfNq2JQPXX4W6u0CVUS6ZTVq6ZVbVGkoPhovmfID3ZEeYsdfAEo0bhxoUqIGyI9vv4HnWYHnZwW6fq28JOH8ONJh3vZrLHCi4nMlXaouv43TZmDq9M1UnmljsC8SO34pOYeWnHSxB3HSKtwyWHSdpDzrUfWqy9NyedC5bfeRNYjF59cmMsqjCDQlsz7ZGVWPclRKZyqq8ug5iLTJpMJMAsBuIOEYEC7dZ9M7mQcN8eadVMCbg1pI6znWiTuwZjSJr6CqeFLZl2944KktGwIhiAhL4kxtBkqS2KTQBQFyBcmZouC1LM0yuNoHEj5Mzyn1cUQqJJPwG4uvgDr4pGbxcniJzuHX70VNAZT5IQH91T7WDlzhVAWKr4Q0OSfmMgHOH2J0eFGT3oaJS7ca8sIOfdMPMNpK61w8G5lsCnoR9ZVi0203nf4Cw8Yc22Fj2poIS6p3rz46jZWMi6LxM6fGAs1dhxhkqnCCT4Z06ieOo9yVgD24HegWnGIjIFGaxHSYMRBqYHvwh22DgUdEtzePUMDChDYdXVsz0B9Le4AtsBM9n3Wqkx8KF0aOjrU5KmokdASXfd5GSWSwC1cnfDSo6HiIMCcjg0Ve2j88b87RoD8lsoIx9Wi6bVfTtNOsisF1PHsfvaUPIe86AfZvGcGSGni08e8FoKeK4EiFM0tndzEdJAN2RdT41JHDgm2XL4q617eh0SIwrBu1pKVIQ1MMubpDW2sXEuGgqwIAPqemYfAuCmE4kuUpEHdcWfcxQHcPu0FtTRgXFbMM9OfiSNKvDRmrDjj1EOPKwZYmA6knCwVbB2jkD8A8UqgDDY8OyQSemsLjsRvWspPx2wBc39dsyjCpucdHVi8ihawzTZNNMUArS5uGXJiz3sr10oN2lGFC6PrNTwKzwcJpBzfVtiAVY2qvdtUMrDPAhvZ8oX3z0qS5mhWTFP9VldYiimOkny9E1xyyAfXiHI7gbhDGX9afBdkItfQOqkIGeGfDmGQaRPRLzZxKUAT78tHbP83rCGjOYwscKMicBo6EFrccRZEOHGQvu66Pw1mpzJ7TSSIzGB5U53OAF8DjCvajdu71iwIQXARAp3SQfdIqBzAoxcqYeMk4tfAfQJKzF9sPATDrWw9GBafnzALA6JaeINZINI5NFvEWENv6EWZWphab6e6FiWuU7lUAcgg87tagxgwQD3Nbnho6ZDEy1s2V93hu41pd5pfGaUy5hbTvrLOmrwZDuEOuCxrnbazn68ytkDRZxuNeLgeeO51nq0jTr1BJcgrqvhNutzYCiyrqb506l0qPZ4KmxmJa16y25nYWw4pAQs4KKsCYC9xvlbavAQDYImarR2l6pKpPoE1JdXG9M1MB2gTDNqdxKTw1uSpulDK8V7pewjp6bxtd67JEIvQUvjtyRZ9Xpn0H19XvuR5P1SBZ08uqVqRyWSZ9CunLhziCdTAhtfZ7fO0mL4I63PTUVh7CSPTDJHHeXkMiVJ3PXQOcVGhILTPdgYNbUg8wQxMZUo2fDJuTybtcuNxsjdnmIItOWiDtT9MJHtzGM97W52tEYRW5cmcrqMc7uEvOGE2JmBAYl4OkKuBsCVrOikOXAYw1duxfsMAQwC53mWNe7CtNfYRTlKjDLemhRgzqIlQ17xoA6NPXtDvfGjGwsNHoIMdBTkVF5FspkR1KXu0dTSMBx92503VMdGGwwlQpWgy7qm0ehLtuKls8Kcs1CXE69udDGVWgEfROTcKPIIUjCmLTMFw5BxBtklAPYAgWae1jn2w7pdrBEjLBdZSRvHUFYdvlOmYRuOwTozWWXmA4HAxPUtrJal6WsyW6OLPZp62icwEFl942HYyihGjTxQYw2ulHJlEIfKIkyXF80q8D2Hp0OEcak2TenyIakYEy7Ji8RzYYH9voAj9k2xXVz4NCgEpfrEh7PfSt6dXYmJYNd3ArMi4fvmIdRRLQoxzgMiVYnDU9rJXXQo7xeYG4LDkeRGd2T01UODMF3oohbOjlZdWxiqnz5Gy9GiBV7YFH5OzFrYkUdWjjTgKOgiZBmgFKKClKuVEm9CUgALlDz2eTYvH6bpQE5SvI4L4MwGP3NTW90ZXeVTNQQCMhNXK5c8mnEKvZ2rBhxKqGfrkuonmqHxxlcr5Iua6EfSt0iNiJXRaHhbLWq4IUSEFR7pwzWHZfzEAAKzkuYp37U0BWMHuFzMh65FslfjVN3maLTdPHweenauIJEWLKbcBSQYBzycTgXgXGNJiZ8TGXzOlsfyO2RbyYDSE5CUkWQyH8PfTNeBkoNXHgk7y82eDEWYSBF5m5xODBvxwFcw8g2jT7ulY0m1RH3rila8Hws40ZBsYRSFQu3RHpQRIsHcAgkWxSoOQNxSmawJFvvREuQnzY52VACEYMB8nZH60CgiWCXGP4Jfyi35vgekp9JIVcMkZBPhfYkQEnK5F62W9amW7u53Vz4Pf0AyabCBrmCycrKGUHaxXul5q3SM0ZqSVcxGbFNLTyflP4rolaxJb68mY3BDMX7jOjU25tY9hUrkVlImF7OcxKSCSPF3KWBIqbvPOHfTzoFtbM74m36SLSqVrg6hqniu6EOiEx6hyZtIuJZ12FGetqfk2SeYZmjbVZGPl1i3GsJ20EMIqdp0gg7HCIQ8YMvLbCx3z3oSijSXdYeJK6CzqM6Zeuclv72SeIQHXEE9SLcPzETkPqEK2Vm4QPeQVPBRGA3wZlaTjLAufc9PO9Hwnv2E2WdvarZCP1NJvyq7mLlSysbLZMAUwMMq8kwkTDd79vofsKPLiyirxBQVEXkR4WOUdZ4UridcnmOEvsUAx0qqbmd0zojsfF8TsuoOh8zbz3zww9f8y4PMgpMIpmsJmeWTezfqglXi7L0PhnaPrBJ5kUDmXax1qwDxRqZWaSfklPiAS4nhy4XncLtU8pE8wdmZl1RouHww6X496CWgqC0CKHTS9h8D0dPPqoq5oUfgJDBaLKVEBr9D6ho9d8bHJSIVsztVpNyZFMaNbdxqdYGrz9nUEJzjHdfqwJNYDd8a5KhrXyaW8t2XWDQBe1oMKCh6jQ5dozMGexAripDWQABk8gOsAP59cctS0JIxcUcnXypJCjB43NtuZ9TNNsqiw50lnVfUDrkT6XT607JHUb9TP4NtjfPVQBcIsILJeBx9d0OF2N79UD6egMpNGyYZvNXoH6aBUJibKRVXlTEznJ47vZAG8YVfHPEOJOBUYtlXwpkpxEJFSHBS1NV5MdFE4Jf5ngbxv7FxMHkLYryvKbFSoq8kmCqnJOkBjAeT1jNVLY4WTJl2NgvhdVYGecP6Efvw0gcznkIGTFCDmFa3fjS6t4Hc0owLQvo7gpoCtBdIRjSWN2IA5GLMtiPMj0DcLNbhk9RqvnmpFHA9jV1QUCcZYOUHBgnwnxt2ItdZuJCsTmdTGV7d4cs65u2Pv16PoNAe0oiyU9HsUumAA2YlVdRSmCVguEcCL8CFMGaMyEtQ9cr1lszHe6AxaE34b88nIyO2BOaU76vRESXoGoQVkxTIU8WmTXC0es8hpx97pkkzDOFLt5vLOnc8UNhtziLWE4rQm2uNK1dtCNbnvHq5rMgfy1zshEWpfRWWuSlzqi4tN37lbTX8q8964z0o2KjuwMU0rSNAVAOxgKj7aiQFTtibApTGLhmZTNNYPuA3vMKY85qO3JEe3CRVuPQRDUDJxwBt9vMHMsl6zNRDQnvee1fSszxrkMPhmPp8ImDnvvM5DGyLLoAg0F6vToH5URTBYZ7jaUOFUAgP531b8BcjclOe7yS87E9xcMujbvsU8pbcNkpiXlwe4gTwnOi6gfReAhb3CkhkMVBWq4gB78Avn9sWsuuznqOoegDSM62O6RjKXdIdJCdtxH1bUEN8H9pnn88hTbEqTZ4YqPpMy5y2LjZdw6VUynWrVWWF8Lqigzr1B9wwn2806Vs8dqs5CyyZlWsHQsC50CNOkG0RgUy3wJYSl6AWWWCNfwuxlRmKR7d37gaqQkg237J7apJSqvX45NtDkwFPtrSNwc6UHJkQ6Ujj3Au0lCMkyXuQv0RritMUnAnI1xTZORVOT5QIH7pgnaCebPUR9ZIDUDwr3bJP8F7fojzQqMBPsk2LWtSX0BnAldGzX2PJbVpVo39Onsa0R5yfGzCPqKltCwH7GIF9cLzpdyxDGnF8Xl4ZA1gHiNYmbYrtDW5IUIJhjDZWeLroTlDmMrWbVJfS3KvqrmkNErlNSGvpw3tnpVAdClIcu2iy9HxfVTKiFf1KQkCJu0UXgW2PQFl0EJGU6uxdamQT472aTO6tNTs1YEmfduReVYJqtc0kvedlgB3rdgmOpVNGKoVLi47wYy2oLsxguvqNsFn8emvf58BdnmAXYzQ52iQfvY43iw6EGYokWd8uwkONTf1by0UdHu2pCc9VbaRAiAzAQMcbnUum0ufJPFkWv8fxDVFXVTi7CHr9rpronnreacJGawfYobGhmWioybL3raYeTIqzSnCQOgcaDBCe7qXTzh3KgPSZuXrh2ZvOlzlEndHpH1fZ68tNYOonxPnUN7iHjVJ32ylvtBiP2qElCunJFoKegYwgOtPsKrT0X7PgMzOQfq2HaEGJX3WkyaBsOWzmGPN6XkSliQSI4FZ3210Q2kN7NCSHdKFfSpbpA375MTZ3fory7wSu0Bbf6MbbZCZcCOwga8hk8QhO0FcTBIY75fiHK10dZ8A723BWgGXpIIndCStusGFbOXG1nLytj6pllgpwf9ishKtpbIl2BmTcZG2Ytc2Cx9C3wQwtlheD7lMzCWEGKcZ2cexqcdAwz3mJ5x60fdqclV4IdZL4yCmZqq3VGujllMvOejag2Os8piFFswCPv5khTzcLlkgcWhx8P4SnYH4dVJBARgpePXnbxnoWU5KMmrGFVAG6IbB1KyfPjkWtqGWsQ0TVxhIjf7RwlmpOa3ckcR2dMcylG9pMytHnXAOOeOFbLtnopwL8JIl7o17sLlhKsLAC2Bb4kMJmKmxIIv8sn18w8tNO273sOU8jAcBAMjHg3C2iCN02bvaOUuGkmYEBEsh9TtY4LCcd0W6YrPXUbQSITNoGkB0TqgAcMNmLBMfY05URhsoMXk8MQ1KwH4XCa9ISczBCeXtnt9XA5LMn3t6fKbqQKCnILL2hqxa3XEumrS2fFXjufGDfjzZOzg8jQq4mKgg0d1bE5m7R6uTIADO62pghJ1GROLYRZpxFFmwxg62EbQgHphN5DBLmUXauhn3cwc5XEcZqeYjlOleKzuWVU8gXVSMYFYNO3omaimkAyV9chpAC8oav7h1rPjDxes4oc6XIM24BAayTMsFSasoIVDpsJAKS9VrcxCCkqeJ4O0Mw5GhGhvtfgulPFvW6iVQfESbozPi5eBkaDMntHznxPjohCBHaikiRzBaHfV4KRSZSym3YVuRw6vXfDOurirXtXoNwjpYUzyHcATBMLSOjXb8nl7XkGgOgYhiPnpM6eidxiQ59T9nrCcp97xua9g08B0eHRI0gkSVVPqEOnGwizy1bexKb4e5AT2YDqNt2p2oa05ltSPjqEPGozvQfCan6GLlaey0In6UM2SwW2EE20DnyRAtcZhYVRkChDj7yBnb7tEMvtDzVQq9Dk2occuvkWXhxylCW4fIKoobFHDMccrfN6d1y7kfL4s3mV8JUhieYWLA8GfwdLIyMB58A7bGtEyfyHvUnRd0akB9zLGcb9zCcVFhkRdG1IkLHMLqCrnG1nCaEZREUkxIdDKWajJOtBbBofh9Oxl3tUXOVchK6U4QMZS68gnUF0u8ZM503F0XP26WVenosK136HuNOwqSZmuWd8n3fN88wUAUNa6l84fWkNPZInrZPII2GjsCAkIZdGP4vz3OVOTdNDMEegfa1xSPGg0EchiVIqwO0Q6eZO5EK6blXbOFQsP3NPeBrnlq5wIvTIMCcmMTnyNiFMj2nS1xlSF50IYW3OWefPs3elWVCmIgRiJK7yDSsOjfFHRs236z6Nbtftv8iZRikfJRzTfmqVKfLqu1FIYQNGke4M2QbxTFRNNSWzEmM86eACkACVjfgDoIXcVGoYz3ocG5JY2GO5RItRp52V2JMylqFKSQNdgCrcydmfR9Mxc9EYeTpSqwHYekNgLEuabzxyAL254ziB3jMPTwBQxlHiZ0ynXbz5BOJllQ72LpTcY9PDwaDrHOqgB14C0gT8HUtUv4FNVpKHM9tC5r7dKvQxOW8cNUOjuGEgQIuYyEt92tAsHQtYJpA0WZBbZqvJW9ZrrQvDMkFvccqpAvY0oDQApLqn3Zw4YCHJ4KUiAj4Oz6VBaiWqRI9LhRoJYBoV0m3jd0b5WjEBGEF2ZoEAkKOv10czEf3gtiaKpIjO8pHF9NL2cIM38Z5jCqUG2YzsabS4el6yI2qNtb9yn31v2pWXR6za2lCAyk5rCNXtTRA7QEgobWH2SxpfSd5XqwCeIYPkVzHngFF1zQ3yMb4mH7xXMy21B4pRJGYn4f137qIMd04ZRGd9UAxFbyU0VKdMnyrg3iI4Y7ErrdTsnMQrw0GfI2NGPt8JN0EG5JmbjkjLauJ8pgakANiTGXd1jWeRksdsOJukK0iCKrfSUMVDPR6IqZuX856tqpCxQWkvDVhXG1WxRbUJndWZzuAv5c4Ua3LIYTS8HQo1ZImuOTnb30RXA6LBqgA5NInzkcsDyd3g8DJtWyqB4TC4aytzVcakUyB8OEtnMAR8Aa9vVSQAF4B0gkMvotyZLWCuBnKlQ3LK04dm4qcTBZ7CxZgoUt87xcdgdsh7K98XrOMHO6f8oqmiNtA5UOqZhopZzl1aAvXq9ZN4YeITlyCoe7EHvBqzUTNcCH1bbpIGoc4iRBJVbvZokxrBqlUszdWgnSO6xd7NbhliflDZm702J25Uqv4Scb2oTpjmc9CZtWiaNJB3MZrZIVRzfjkxCGdJTYqwjFxF82EtWEwgwu9kn7RpHTilt4h5tzgMCryRS2RICuhbtJx4xgsspTm7g2jinVBzKuWDj9RHBS2fziZ4jmxEhJGVC88WegK7JL521neqEN2mQiefPxsyRImusoj9zVjUw57D9eIWE7r4BQpMJQ0DVfyD2tjVuKogsN7DZ9vQEfh9JoEazNGwqOGA1VDQr7ohnMFXx7N1GT3unN8h4eXZhpYfOUxUeKfnJLqjc9F5QtYb0JGo1l0m0bwDfahQa5ovbtO8ZfOSDhBywJmHH7lOIErqJvnzkKXaxTaII9tzcJ7ke5UV9hiNIhHiHgaeSQ54oYgH2DZ5um2kV1isBhoGHhvVkcvcXPj4D6h7L2MH3ybxpK0grrbFf244nmRVUCQzJ82nWDtjlOO11PUvvxOPajwhJia08NqIXn98n9sBFTDZ2c0X5juZDTOslY0iZifLf54oSWaYpq4AJy0yC8Py6YJuRVvoxAtpIhHXc66sAQc4icSn1IQ9QwQmNjLlMdO27VNeyjRj7DtIBSdhmJy1sdPuT9QzrxaqbsY7JEJ5xivl5LnLkt2NgBDJM3Q4gWsSVQOmUihrU0kEyPAKsdKDONZD5QE5B6UPMYXEsv9yiRGDPdDdapg03TGtngTHsSfyIsab2nieMpyCh7dDwGJZRieicN5aZe8Jzw8mQL7ow6wTGmIy5Su9md6AN8sMrk4zDHevD72epB0LeplUbymBInKOgax9c1am2BHVrlSv4vIxytzy1RaM3QiWBAjOLXOz7Dy2exhcK9NpJW2u7589p2u5bjZxXM8ArHFzpmr7YF9zy0O1H0GhFYdL32ZvC1dxblOMn8JCHmWurs8ejiXxDR8W3I4HjdfVj1VlZSACTfnCjHQ1fe7pj0J1bBo8RfnqgjQ07cveh9HyHSujOOHIrSfgNEuC2pydaNWBMiPh7sITlHcyyYB99cgyn5hKdPf2Q6QJFLSnhcnQaXfWALrYRN7VIpaOCbHV2SZWTIvYPz04w7kHTIgUjPusq3w9kWSEB8hTjCuFEjGfqzniMTrFIojyUtOYP3FQcuDJMnP8DPdBi9RtFlqABkyMB8VGzlurfz75MtbjVvw8dJx1NLJYA7TKBQqMch2qLNuhNhw1vnEceuaFAhKvkkl08dawu9Hh0eSQIiSXBFSZmamTyFpYwQRSqnxIGzQEXIDX67zT8AcNhzw0gttoNLXpwmej0ygCGNwUWDMpf3e1gHNlwKDYTlNvJ8AgxAdmjrcWUO3MOkAhCXXNI3cT5pc3cvmptwLSJjEnDo7DZgBnrK0M2vtowJjEjfCEZXVNTNtda1ghP9pJOWSFYF8b4sw2NMzDzPbkUAFitXlR5VF4glhT8EPuVSpcQKJmp19PG9R7GV92jwaDQ6yjYrUjeA0Sl5n3r7nchsdqP6278IdZB0kv0xJL0AMre7uMjaWxPOmNOmK9tjiEkV1zHB57KK1t4syOyPod0RSz2ckevAX1gHS4TQEW00JcrVDwJRaLce4lfvqE9dUDbdMISfUiKQ8RpW8svUsG08bPLHfnHiIiDzl4WRK2McLpzIFGoToUJGnfrw8LWio5hddAM7mN3EAPHIFNn1nNZyXatqFEAed6iKqn67NX0yQRCsDKpPGw9GUKKSXNDCiYZEx9zRxJM4eBA4zokSSAQontN8E5Ir6aUqOAt7pD0taEb0EupgrWa96Dbg2qEXB0Iyo7Z98WIRS18Igwo8j5Gv8bO9SGjZFHpuN03WmuPiDNLDvEUS4UGrHnFaQyDWPBTToQWOWRzYHNtuw8EOdHm0WEI3i0YWG5XfppuhCzVZnYhGteA9Lrpz5LziNNlXxPI0KUufGWSU6naU3wgZ86QfoKsiwheHqdwezbyoz2NeCBrELeSXKvnp5qIeFFe1yY1smsrAj1D4hNZ3g3ayDzdvCStyjNZQHHn2U8Kn1bTXfyeKAp9wiQJBmaUdSP980g20Ns2ppHfx2R7QftlfhegfFNZT128yhKKlKiaDpIAEifUjc28WV5evcoLqfUQTSXDNMeodDxRosHvKhJgHbzXy7BV4OPXV7QrVUvu3PMVncdU4wJMzXkiDnb3WAv9apAkEiMl5eYxyMpJVilltABiVzUkO8pbrMO6DjirxgCP2X0AgdPgnThqaWD4KSANa1jPUKvWiOyQqBQANnkuQvK2VoRBTvoCCOyyvkICJxGR0469nvVnApahrgdJzLVSXUfX9DHQaUY9ldiGDWi7OrzSTfegpYdra6yrtnuKA0UCWDTsTj5wtq9lM9prS3w1F5BfzS7veUHtnO5wflLvnWTr6HlyA5PUNr03PRppLGIPKnRK9qxb8RWJIW4fumS0d353gPGYaS7MM92w7zvEAAExJXqdRvwzAUjFzX25Uh6IT3E3piB7alYuIZWX9Gp1j3hX6vuqIeOPbZc6j954tELxVZsHFJrRoGSXbcpAEw0O5T8nfWfA7Wi6Qo0WdxMXRTn0osDNt0IbLaCyyFrayI1FhQgkt1F6zidr4eQfMvBnEMkW35xHpOg45Fi4VwR8AYWqzl4nCsqB8mghB8mZQPHX61zf84F6xkJJw9L6Xva7fOYABFU8y0CFoUvTvRcHiTn9KblrgxDiCmWf0F7mdYRGfJLdbRoiWJufTi8M58GjReK4Fn2NzbwTlMrNMsWiB3QpjLvMEJhFdG2XZleoqSLvTFlkr0QwTlr1ECBy1ixka8oEIPOwGkbALrE94gG5x7hb0Ib21uxAgwNdFktvB6CDVHt9pXv06sOyeyWFN0afAE0Hft9rLadL71GjXJohIuzhOg0IjLP8vZfnW3LAZuBIU2WqlYIz1y04yAfFAR35EcP7Xqy9I0eiLvQOtLxMOwEJ0wyNo9tlI4Ar8Aha6KZdT0MswZCHWmVpbYeMt3uyYG74OyRoBnlTNtsI7ptWORFeiG37ab6onJacJ81J7hdPWk7XCOwn9xcoyHf4U3Bvm05mpnCgG8IdubpGtMGXmjXPDBS887pbT092GStaSy8itBWCVP50LYlffr9YsHgCZRDRvCkqeUoCeW75M05Prtl0ybC89zU9ughzIbpjdJIxpvuocpW87C4jDxfA6CfZ7PBSroTb6OFStWhTxL72ZEf9KpMkmeiK99ZXjXCEeHF8xbAUbTh2oedp702Ekva3asgXk6DpcSrRX6KDNbDY9uAOrUqKnDY0iJ1PSO8NNreikke49rkAjgyOg5fEY09wIdN9u1Y15SIkr3vtARmcI4pTSTQj2SZY539kNSod2OCtJjgGvBML09NAJytfh8ovHwo0mD57SEYaPpr6uNmUSkgXISkrvNVfRbAzHDN4XVutrB7ImU6ZyouTsB1AmQrpJvZ1ewxWFAlT6I2UpvGF7mKACJvZHbrYoeR2IQD9x0rqB7GjZ7LAgKeDlHLH8bMeOfBRBC98eYAFQ0lZMwnEF3gRgZOrZklUwSz3vU1Hh6OgTyzL2dnr6UXhFH1xRcweKYcMaKLd8ZyR0E6ESsTYynwEjMwINTTXyh4JSzfy7H5S4bLQNBmWSdGy3niZ0qMRYwvg2epGh8QNFS3pgfcpkATDuGy39pcO910mLQDHQlWHVjcaz5lZepe7hewpLDoJnTPV8uqS8INamV8QKA0rgv8DI1xQRPSLX3NkuTFHhpw1N0QmY9KIPHLoKVVCaCpyJVYaPcHjvwlZgt0DvR4IB6lQKraUooCBN4syaqlibGfhemzRUXkEwZhbNUFQuetWS61E98m58yrrS5D3eqDp5xLF4aLClJvw8ioOpTByWKGESdv6ubxDIfZxi0MdexO2eyiIzzEEwmWMNgsUth2Jy4MVFMUaeXCGBDGMhNq04UrlOoknRLKj6sxyclXdbSo2JiSPa4k4wkQ1eAuqnDYSZCMR3vSEjG8f5wpMM4OAzuOJBlBES1L53SjQAmeBkU5QDVDc37v4W8hhG8HqLM4ugpDITVmnujTmXsrJ4z5QzbwzqMbIKerHWfAoPnIQ7kP7o7APunIv1LVHALuqssLtprTDva2ckg1IX6JKUZf9H7G4CctUmJUtfNU3yGihPaDKkDPykNo2N6IO3ikEc1Ym3WAnRw8gXwe82dLdgTJ3z13COjQmLu4iwb8TPLwOtT1vPvZrpxr1qDKPkUPSxFesRWmQHGgwj0Fq0XPCiBVJV04nJkssTd3l6tZdejC3R65Hr9rmXC9GKP1IU6qDflRckM2F1YEJMCrHr67m4I0zuND4JRF7bgEsrQ7NwX2JJAAfYdyIXShoqQ4DvBgHhXmNgT7i5r1UDQEBO3KLnhJNkoSgeRsJG0npEwI0ziqaVT4NdQt7GAua0GpkHms8hcSAkETfs0GSc7pcECu1uZ1d6SnjIFsOhipJvpfCtYE4NBqBpnH2DAFC6jtPhfCaTyzm9tF79HnpJBqZ3ffYrayDRjWH6Gx8cWHlAUS1bS2MjoAfyweNsPqger00gUf2uPrJmbtph2GTAkGn3mP3K5vEMatK0kWsUTmBzzbSfCNirTFpe1UwneSPrOiOiofq666siXspxcgf0CdgNabyCeaT107fM2Gahmb3pyP6jZMB5yfEm79LFO4JwFJBzQRLZ7fZkTVXwGy30q8t6JjkL8qfPfcVytmnbehCOMCQXZL6RtHRL4XouCBzK6ZIVFwfoMJllxcd1PDi8XNh6MGGC5cCTCmJLUY7RIOVOjEBZF9NeSfkzSxpvwnQVSTIwXFShcRFfokur0QtEdllpvj9LXppz1A8s5XO82wplkcoSRzRapvPew9pTECgYOfcQqWyWVL9bUtGcolOAzMWrvZpRPY37kiA4VZfmt8Tl4O46M5dM0lRYVh6Yiq9HDwjMRDYRawo64O5slEhuLoROhpL1EN4XQ9RgrAjwdrffBi59wvBaj1ii74SboYVpEi7DyHd7siRRPSx6vN0iliHqkWNBsec6o9EqZ1mKQQKHTDff6JlXnYz7NNqldcQECUyW9UaDBqVOeewwuBU8aNcDK0zOzfVll5r0G78HAISVuNTxST8lXJoekqOSfnuvGmpSDCPdUaq0mHcPWq0GyFjizUG0KOvaJb8p7seGRyIZdI1EjvBm9CU5pf4m6DWe7HGXxJW5RorqCoWFbUtk56zKOBBVufuiYXiMAZUffWJNLnRiVogSpSm55X3wFanq7KCZxoCqnhtP0uDVflNYznoQFaPz6LMINoXrwHM64CWMLIEFGIVZ3BQ8mNwJwEW11nW5BpYriBQlJlhU8GYiZ4WDTmWKxvtBoR0CNZHox25Y8TBDal1s1L1d5sRcVYB79DtXqGJOL2cwi4E5MteNaNMTUi0ZDfFAF2Paw6F3BClQNdpJt1NPR9K1K2so7aifyZLEaevc3IRHvC5YxGzuypgGBEPGw5fHS3vcjaNoKd4QbubgZUTWPhKuoYQwcMCSpME3rExNBWv5aiYD1zBIopFRek2CjrDhRZhF1ljYUw9QzT6EGSubPn0FBoHt6VUQXqjIfZifpBrvPyCMXFtxdIlIhRaJMN0cTBLVQjRSJVntDC7Mc9aYv5fBe7Br6lAy9GmhMYDuS6e9ehhPUUM5jDCwUEObn5EvkJC4kKpQ2XDkVbdEdTpKsmWdQ7QCDks5d5mEBdEwqgzCv24vmM5jEEJrMrllWdDXcP9GCDiqnMBQHcCM9uNnMQSYuRmmAxgOJM1N6NCMn0Kds5coZDNiwaP0DRBqlH7ss6eexg35xTdzog0f3qOzf1bVgQSfUcTpv3lJ3sbVVwR3QXCRhw9n0UYDwYlnlIrcxbUV29qJgwEx7NutBV5B7I4Fc3UxFEPlwv8OvYmeC6Il6WxvCmOVZT4PFX4n01LvY95nqllrVWYaOAUema9OMNTS2uFf4cNlqLrSINXbMlyQNGEyNJERKbLxM6wxeETOoAUqCzBAfHhiJKbXQXBdUgqhOXPDgnveqtt865xSnlCNdxBhdsYPHSfWadpSbpwUaVwqyWv2cPZE3Cp6jL8UfyRoMy8VT0j0ul3kwJ128dwQX3JxFrAGr7AzJ9UVpQ19lpnBRlBO9uJhcSnzGORCfpzs4YIJ6a7Icjoeb1cYihesuuo2PpBDYfXbqzZ9BP1F8EDNhM66cjKHDd3Q92A5AiQb3QUMZScxkBgbveFBzVhDbpcQ8IotGN2qjX9SWEe0DJ1LgVrBUCKI3p5MR5O9SxCAHDFdQoW7tpagJEiwueXkSePoQPFf5P33WxHZYCuWdzsaUQgvWgBuB2lnc4mSkHvcZX75rfD22LvCFrJJ0gbJzaMZjKVWTV6NZCPNSFV6FeOBPX9uLA67SQoIs4vZ42shR9MnyjJtfkeBoGjglx0JujBI5CbRQgkj460WToajqurWJcHJwrhZPMAgpdOpdK9XWSTOp3Fxvn1t0IUfdbHzWhahgw6jiqorti6a2eEeP6VZjkOhXkJKsHTaKdjJfG2TRwSmoyDHnuvnLdn1ha5KNbsgdrkIPYsFOh6XZmGssk5uDWM1G0rVVMUoD1UWmylnGVnkKKJmUsB7W3YCTh0B3MqROA8SwNpQdZmGTsXTquBPifeZpUpsHSi7miMFe7DA8wIy8GhIdyUUkYuvS8ZRbqwmurFvIZ5DdqGsQleaq3fBRrXVdVC3XMLorboLEH5E6lj6jMuUpZ99Nku9n4vBM9XHpOUYUOxzibl3LCB6E30d83eyU1nRlQ5QnswV2nPad5VwLeOWfTN4MjASqV1GECfBslv8bhWYntSsP0bsSM1QZvyDhiNAiTbBDHqxyoacgKPrn9aZjYnB73AP7hIwCZZZeoJXnvV4XIARwdAEH44ome8gRsitIcSE60wDGwDYlaU1LQLF4OCwBmzdS1XKSvHEPFLuod4RPn4IZRuZULDGKgmIEAr3f0G9Qyy8bUawh4ve3AwbrVRtB9NAO8UxOl1g6I3FkGQevqfv0TfbcUJI3DXE9pViQeiPAsPXeyF4KBPM6VP9nUSwD7aK8tISBg987kmfXZnElIl31wo0Yek3A4Z0vZhyTrRySHbt3CeMisHZ3KQscT0bfwl0mBmLW1OgyyvtOjbkTlN4maL5m9rEjqs4tDN9Nv27NVOnHtTwzPMcUPIxJOTVBUeUNmf60aeBqJAecokAw91nJ0YzAaK12yVNxJFuh0lR2Ekw9XEpViH04DRLnTIlI1Qi5KPUf6UcGn846PZT7K6pMu5CqBfS36XuRMkDWanlVoaPT6GdqEvTLCvL5nCDZEnZJl6NnwjOlgukBaCyUlN2FcV4JKleqV6GsxJFpGg4hq9qIYwh1bSktzaMMfcPrBLBvD8IqM8CmQCA8RmA85eeA7t2HTYMQjhdQlT4xB8wbPeHOBbIjrAHwJkSMfoawl1D3ncQWdbWeyuERLqzNzYOZChj47t3Lg7iJtODWIDqGAXiZ1v9Etn6fZlEBEKAXK4xDtnVYNWDieqlU1lJPjp5bbuwqSGedPALVJgfqAS3KZzSDzwIkwxtw9dCeKRj3axdLgtvIVYmRB4L6dYKXVx9qwQzrsOPkJQ39TsmOn47mG0GCFfDmapjmeqKyBjMyJFV07bKfDiAyI4tPJShPH1DeSIG36fWBosH9tsK7nlNzPSVASn3HjkRObzU61wsc98D5kjRR5B8Jn66RrQNK75RfxEAdsaR9SNuFXYjVjk2GGWEICYKtdXaUeC0REcxgOFB1jggYmwfCvkP7us3jjrnI3aO2xGXwjMbl7Qlc31aw8AUU2jmhXikBRR18IYHEZHCjiENhpUdD34yDFEt99Je2Gi5IYitzKvg6wHikxQxaCf7wZt5bJ0FEd8XA7FnlFS58x483d7ghi5xBvNfUtkRlwe4in6UcSRLWkrZsCYUfSjarAo2NL1guyuMbHB6jVHUhQBkUnFhKkZjMZ0csaZZocaR8B5FtQxcqzH9ZnEZFGpoKDu0TEB5mHuKQquJpQtUlpdx4qd0FrVNfawh7PW3CCbKCxuEj03PCnW3NzAgS9FPlMl5kZtOMx2T59SRw9qnbCs37ghJtMYgI1iaEq4ILNnVrDZ2OMFO3Pmp1iDLuudI9ubvi7HVclBfz0i8z5CJmbNN1GRsXtsUFxqauyAeO27ECVHHiJBCpoWmVh4FcsGcFD8ISFcPDQCADNomO5htszRRQRrxKYk7KimjiDh0B3NdEP6H7fttigwfTWvjhYBEB8fnET9wqCAyMonXaaPkq73N7TUdlFSsxCdNkixI64ksu4go1gdB4YxZ9ALoloPc2vUpjn18EX3x0EVabXKEHWNIgyfcFdbrjU6E3cQ6udgfH8AtWj8yhxwgK4P0fUqqJg3le0MPo5KybEWuTtoBsdcQ4WFYxuUcTAXF2hwdTwMhoST9OwKL4K4eRuA1g4SQqesLZmMFwXsCFKHRSO8bv48qplLX5QnGN7qm85OygqsV5NsxTpLCG8QSk7ribN32iUfkdPc53PTmSDL8HJGzVh5jaCE14StYPBd8g1uDK3SM5F2RQPV6pzUQDxhgAMJFv5Zp7bQ4SrqCfZxiCp1prx408tK3icnp6GyZCM2nFuLopKHE6X8LJB44Z8XjXBipeM5rQClrhpxb0TBTkmhWdEer1pAkTnMHX4PLCeowMaz5Q2KG7cEhY8VJjOhK22Ln"))
Use two variable, one to keep track of the longest substring and the other to keep track of current longest substring without repetition.
Iterate through your string.
Check if the current word contains the current character.
If it contains, then checks the length of current word with the longest substring. If it is greater, the update the longest substring.
Update the current word from the last seen index till the length of the current word.
Continue till end of your input string.
var lengthOfLongestSubstring = function(s) {
var longestSubstring = '';
var currentWord = '';
for(var i = 0 ; i < s.length ; i++){
var foundIndex = currentWord.indexOf(s[i]);
if(foundIndex > -1){
if(longestSubstring.length < currentWord.length)
longestSubstring = currentWord;
currentWord = currentWord.slice(foundIndex+1);
}
currentWord += s[i];
}
return longestSubstring.length < currentWord.length ? currentWord.length : longestSubstring.length;
};
console.log(lengthOfLongestSubstring("bbbbb"));
console.log(lengthOfLongestSubstring("abcdaajkljl"));
console.log(lengthOfLongestSubstring("pwwkew"));
console.log(lengthOfLongestSubstring("ysbghjjrfumqjpyktddsnxftvdqgxzlvrneaynufhgyqxwaqzelmbsiyxaubrqvguvehpmrykhvikkqzwttg"));
well this is challenging but i figure it out
here is an O(n) solution. cant do better then this
function lengthOfLongestSubstring(str) {
var currentLength = 0;
var result = 0;
var keys = {};
for (var i in str) {
if (keys[str[i]] === true) {
currentLength = 0;
keys = {};
}
keys[str[i]] = true;
currentLength++;
if (currentLength > result) {
result = currentLength;
}
}
return result
}
console.log(lengthOfLongestSubstring("bbbbb"));
console.log(lengthOfLongestSubstring("abcdaajkljl"));
console.log(lengthOfLongestSubstring("pwwkew"));
console.log(lengthOfLongestSubstring("ysbghjjrfumqjpyktddsnxftvdqgxzlvrneaynufhgyqxwaqzelmbsiyxaubrqvguvehpmrykhvikkqzwttg"));
Can use String#includes() to check if your substring has duplicates
s = "anviaj"
s1 = "eeydgwdykpv"
function findLongest(str) {
// reduce() iterates array created from split input and returns longest sub string
return str.split('').reduce((a,c,i)=>{
// start our substring using first character of str
let sub = str[0], j = 0;
// sub.includes(char) returns true if char already in sub string
while (++j < str.length && !sub.includes(str[j])) {
// no duplicate so add char to substring
sub += str[j];
}
// remove first character from input string each iteration
str = str.slice(1);
// replace current longest if applicable
return sub.length > a.length ? sub : a;
},'');
}
console.log(findLongest(s))
console.log(findLongest(s1))

Check for repeated characters in a string Javascript

I was wondering if there is a way to check for repeated characters in a string without using double loop. Can this be done with recursion?
An example of the code using double loop (return true or false based on if there are repeated characters in a string):
var charRepeats = function(str) {
for(var i = 0; i <= str.length; i++) {
for(var j = i+1; j <= str.length; j++) {
if(str[j] == str[i]) {
return false;
}
}
}
return true;
}
Many thanks in advance!
This will do:
function hasRepeats (str) {
return /(.).*\1/.test(str);
}
(A recursive solution can be found at the end of this answer)
You could simply use the builtin javascript Array functions some MDN some reference
var text = "test".split("");
text.some(function(v,i,a){
return a.lastIndexOf(v)!=i;
});
callback parameters:
v ... current value of the iteration
i ... current index of the iteration
a ... array being iterated
.split("") create an array from a string
.some(function(v,i,a){ ... }) goes through an array until the function returns true, and ends than right away. (it doesn't loop through the whole array, which is good for performance)
Details to the some function here in the documentation
Here some tests, with several different strings:
var texts = ["test", "rest", "why", "puss"];
for(var idx in texts){
var text = texts[idx].split("");
document.write(text + " -> " + text.some(function(v,i,a){return a.lastIndexOf(v)!=i;}) +"<br/>");
}
//tested on win7 in chrome 46+
If you will want recursion.
Update for recursion:
//recursive function
function checkString(text,index){
if((text.length - index)==0 ){ //stop condition
return false;
}else{
return checkString(text,index + 1)
|| text.substr(0, index).indexOf(text[index])!=-1;
}
}
// example Data to test
var texts = ["test", "rest", "why", "puss"];
for(var idx in texts){
var txt = texts[idx];
document.write( txt + " ->" + checkString(txt,0) + "<br/>");
}
//tested on win7 in chrome 46+
you can use .indexOf() and .lastIndexOf() to determine if an index is repeated. Meaning, if the first occurrence of the character is also the last occurrence, then you know it doesn't repeat. If not true, then it does repeat.
var example = 'hello';
var charRepeats = function(str) {
for (var i=0; i<str.length; i++) {
if ( str.indexOf(str[i]) !== str.lastIndexOf(str[i]) ) {
return false; // repeats
}
}
return true;
}
console.log( charRepeats(example) ); // 'false', because when it hits 'l', the indexOf and lastIndexOf are not the same.
function chkRepeat(word) {
var wordLower = word.toLowerCase();
var wordSet = new Set(wordLower);
var lenWord = wordLower.length;
var lenWordSet =wordSet.size;
if (lenWord === lenWordSet) {
return "false"
} else {
return'true'
}
}
Using regex to solve=>
function isIsogram(str){
return !/(\w).*\1/i.test(str);
}
console.log(isIsogram("isogram"), true );
console.log(isIsogram("aba"), false, "same chars may not be adjacent" );
console.log(isIsogram("moOse"), false, "same chars may not be same case" );
console.log(isIsogram("isIsogram"), false );
console.log(isIsogram(""), true, "an empty string is a valid isogram" );
The algorithm presented has a complexity of (1 + n - (1)) + (1 + n - (2)) + (1 + n - (3)) + ... + (1 + n - (n-1)) = (n-1)*(1 + n) - (n)(n-1)/2 = (n^2 + n - 2)/2 which is O(n2).
So it would be better to use an object to map and remember the characters to check for uniqueness or duplicates. Assuming a maximum data size for each character, this process will be an O(n) algorithm.
function charUnique(s) {
var r = {}, i, x;
for (i=0; i<s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
On a tiny test case, the function indeed runs a few times faster.
Note that JavaScript strings are defined as sequences of 16-bit unsigned integer values. http://bclary.com/2004/11/07/#a-4.3.16
Hence, we can still implement the same basic algorithm but using a much quicker array lookup rather than an object lookup. The result is approximately 100 times faster now.
var charRepeats = function(str) {
for (var i = 0; i <= str.length; i++) {
for (var j = i + 1; j <= str.length; j++) {
if (str[j] == str[i]) {
return false;
}
}
}
return true;
}
function charUnique(s) {
var r = {},
i, x;
for (i = 0; i < s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charUnique2(s) {
var r = {},
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charCodeUnique(s) {
var r = [],
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s.charCodeAt(i);
if (r[x])
return false;
r[x] = true;
}
return true;
}
function regExpWay(s) {
return /(.).*\1/.test(s);
}
function timer(f) {
var i;
var t0;
var string = [];
for (i = 32; i < 127; i++)
string[string.length] = String.fromCharCode(i);
string = string.join('');
t0 = new Date();
for (i = 0; i < 10000; i++)
f(string);
return (new Date()) - t0;
}
document.write('O(n^2) = ',
timer(charRepeats), ';<br>O(n) = ',
timer(charUnique), ';<br>optimized O(n) = ',
timer(charUnique2), ';<br>more optimized O(n) = ',
timer(charCodeUnique), ';<br>regular expression way = ',
timer(regExpWay));
let myString = "Haammmzzzaaa";
myString = myString
.split("")
.filter((item, index, array) => array.indexOf(item) === index)
.join("");
console.log(myString); // "Hamza"
Another way of doing it using lodash
var _ = require("lodash");
var inputString = "HelLoo world!"
var checkRepeatition = function(inputString) {
let unique = _.uniq(inputString).join('');
if(inputString.length !== unique.length) {
return true; //duplicate characters present!
}
return false;
};
console.log(checkRepeatition(inputString.toLowerCase()));
const str = "afewreociwddwjej";
const repeatedChar=(str)=>{
const result = [];
const strArr = str.toLowerCase().split("").sort().join("").match(/(.)\1+/g);
if (strArr != null) {
strArr.forEach((elem) => {
result.push(elem[0]);
});
}
return result;
}
console.log(...repeatedChar(str));
You can also use the following code to find the repeated character in a string
//Finds character which are repeating in a string
var sample = "success";
function repeatFinder(str) {
let repeat="";
for (let i = 0; i < str.length; i++) {
for (let j = i + 1; j < str.length; j++) {
if (str.charAt(i) == str.charAt(j) && repeat.indexOf(str.charAt(j)) == -1) {
repeat += str.charAt(i);
}
}
}
return repeat;
}
console.log(repeatFinder(sample)); //output: sc
const checkRepeats = (str: string) => {
const arr = str.split('')
const obj: any = {}
for (let i = 0; i < arr.length; i++) {
if (obj[arr[i]]) {
return true
}
obj[arr[i]] = true
}
return false
}
console.log(checkRepeats('abcdea'))
function repeat(str){
let h =new Set()
for(let i=0;i<str.length-1;i++){
let a=str[i]
if(h.has(a)){
console.log(a)
}else{
h.add(a)
}
}
return 0
}
let str = '
function repeat(str){
let h =new Set()
for(let i=0;i<str.length-1;i++){
let a=str[i]
if(h.has(a)){
console.log(a)
}else{
h.add(a)
}
}
return 0
}
let str = 'haiiiiiiiiii'
console.log(repeat(str))
'
console.log(repeat(str))
Cleanest way for me:
Convert the string to an array
Make a set from the array
Compare the length of the set and the array
Example function:
function checkDuplicates(str) {
const strArray = str.split('');
if (strArray.length !== new Set(strArray).size) {
return true;
}
return false;
}
You can use "Set object"!
The Set object lets you store unique values of any type, whether
primitive values or object references. It has some methods to add or to check if a property exist in the object.
Read more about Sets at MDN
Here how i use it:
function isIsogram(str){
let obj = new Set();
for(let i = 0; i < str.length; i++){
if(obj.has(str[i])){
return false
}else{
obj.add(str[i])
}
}
return true
}
isIsogram("Dermatoglyphics") // true
isIsogram("aba")// false

Find missing letter in list of alphabets

I am trying to solve the following issue:
Find the missing letter in the passed letter range and return it. If all letters are present in the range, return undefined.
the inputs that I will get as strings are:
abce (Which should return d)
bcd (which should return undefined)
abcdefghjklmno (which should return i)
yz (which should return undefined)
my code currently looks like this:
function fearNotLetter(str) {
//create alphabet string
//find starting letter in alphabet str, using str
//compare letters sequentially
//if the sequence doesn't match at one point then return letter
//if all letters in str appear then return undefined
var alphabet = ("abcdefgheijklmnopqrstuvwxyz");
var i = 0;
var j = 0;
while (i<alphabet.length && j<str.length) {
i++;
if (alphabet.charCodeAt(i) === str.charCodeAt(j)) {
i++;
j++;
}
else if (alphabet.charCodeAt(i) !== str.charCodeAt(j)) {
i++;
j++;
if (alphabet.charCodeAt(i) === str.charCodeAt(j-1)) {
return alphabet.charCodeAt(i-1);
}
}
}
}
fearNotLetter('abce');
Thanks for your help as always!
I would do it like this:
function fearNotLetter(str) {
var i, j = 0, m = 122;
if (str) {
i = str.charCodeAt(0);
while (i <= m && j < str.length) {
if (String.fromCharCode(i) !== str.charAt(j)) {
return String.fromCharCode(i);
}
i++; j++;
}
}
return undefined;
}
console.log(fearNotLetter('abce')); // "d"
console.log(fearNotLetter('bcd')); // undefined
console.log(fearNotLetter('bcdefh')); // "g"
console.log(fearNotLetter('')); // undefined
console.log(fearNotLetter('abcde')); // undefined
console.log(fearNotLetter('abcdefghjkl')); // "i"
i can go from 97 to 122, this interval corresponds to the ASCII codes of the lower case alphabet.
If you want it not to be case sensitive, just do str = str.toLowerCase() at the beginning of the function.
I think this is the simplest code to do this:
function skippedLetter(str) {
for (var i = 0; i < str.length - 1; i++) {
if (str.charCodeAt(i + 1) - str.charCodeAt(i) != 1) {
return String.fromCharCode(str.charCodeAt(i) + 1);
}
}
}
alert(skippedLetter('abce'));
This version will reject illegal input, accept both upper and lower case, check that there is only 1 hole in the range, and that there is exactly 1 character missing.
function skippedLetter(str) {
if (!str.match(/^[a-zA-Z]+$/)) return;
var letter = "", offset = str.charCodeAt(0);
for (var i = 1; i < str.length; i++) {
var diff = str.charCodeAt(i) - i - offset;
if (diff == 1) letter += String.fromCharCode(i + offset++)
else if (diff) return;
}
if (letter.length == 1) return letter;
}
alert(skippedLetter('123567')); // illegal characters
alert(skippedLetter('')); // empty string
alert(skippedLetter('a')); // too short
alert(skippedLetter('bc')); // nothing missing
alert(skippedLetter('df')); // skipped letter = e
alert(skippedLetter('GHIKLM')); // skipped letter = J
alert(skippedLetter('nOpRsT')); // cases mixed
alert(skippedLetter('nopxyz')); // too many characters missing
alert(skippedLetter('abcefgijk')); // character missing more than once
alert(skippedLetter('abcefgfe')); // out of order
Note that you have a typo in alphabet: There are two "e"s.
You could split the string into an array, then use the some method to short-circuit the loop when you don't find a match:
function fearNotLetter(str) {
var alphabet = 'abcdefghijklmnopqrstuvwxyz',
missing,
i= 0;
str.split('').some(function(l1) {
var l2= alphabet.substr(i++, 1);
if(l1 !== l2) {
if(i===1) missing= undefined;
else missing= l2;
return true;
}
});
return missing;
}
console.log(fearNotLetter('abce')); //d
console.log(fearNotLetter('bcd')); //undefined
console.log(fearNotLetter('abcdefghjklmno')); //i
console.log(fearNotLetter('yz')); //undefined
Another function that may help:
var alphabet = "abcdefgheijklmnopqrstuvwxyz";
function fearNotLetter(a) {
function letterIndex(text, index) {
var letter = text.charAt(0);
if (alphabet.indexOf(letter) !== index) { return alphabet.charAt(index); } else { return letterIndex(text.substring(1), index + 1) }
}
if (alphabet.indexOf(a) === -1) {
return letterIndex(a, alphabet.indexOf(a.charAt(0)));
}
return undefined;
}
fearNotLetter("abc"); //Undefined
fearNotLetter("abce"); //d
fearNotLetter("fgi"); //h
This will do what you're looking for:
Hit run and check your console
function missingLetter (str) {
var alphabet = ("abcdefghijklmnopqrstuvwxyz");
var first = alphabet.indexOf(str[0]);
var strIndex = 0;
var missing;
for (var i = first ; i < str.length ; i++) {
if (str[strIndex] === alphabet[i]) {
strIndex++;
} else {
missing = alphabet[i];
}
}
return missing;
}
console.log(missingLetter("abce"));
console.log(missingLetter("bcd"));
console.log(missingLetter("abcdefghjklmno"));
console.log(missingLetter("yz"));
I think that you wanted to say that if a string doesn't start with "a" than return "undefined". So here's my code:
function fearNotLetter(str) {
var alphabet = ("abcdefgheijklmnopqrstuvwxyz");
var i = 0;
var j = 0;
while (i < alphabet.length && j < str.length) {
if (alphabet.charAt(i) != str.charAt(j)) {
i++;
j++;
if (alphabet.charAt(i - 1) == "a") {
return "undefined";
} else {
return (alphabet.charAt(i - 1));
}
}
i++;
j++;
}
}
alert(fearNotLetter('abce'));
Here's the working JsFiddle.
You wanted the code to return the missing letter so I used CharAt.
You can make an array of letters and then search through it to see if it maches with letters from the string....
function fearNotLetter(str) {
var a = str.split('');
var array = [];
var j = 0;
for (var i = 1; i < a.length; i++) {
var d = a[i].charCodeAt(0);
var c = a[i - 1].charCodeAt(0);
var delta = d - c;
if (delta != 1) {
array[i] = String.fromCharCode(a[i - 1].charCodeAt(0) + 1);
}
}
str = array.join('');
if (str.length === 0) {
return undefined;
} else {
return str;
}
}
fearNotLetter('abcefr');
This is an even shorter answer thanks to RegExp() that allows you to create a Regular Expression on the fly and use match() to strip off the given letters from a generated String that has all the letters in the given range:
function fearNotLetter(str) {
var allChars = '';
var notChars = new RegExp('[^'+str+']','g');
for (var i=0;allChars[allChars.length-1] !== str[str.length-1] ;i++)
allChars += String.fromCharCode(str[0].charCodeAt(0)+i);
return allChars.match(notChars) ? allChars.match(notChars).join('') : undefined;
}
How about this one? it finds all missing letters anywhere between the first and the last given letters:
function fearNotLetter(str) {
var strArr = str.split('');
var missingChars = [], i = 0;
var nextChar = String.fromCharCode(strArr[i].charCodeAt(0)+1);
while (i<strArr.length - 1) {
if (nextChar !== strArr[i+1]){
missingChars.push(nextChar);
nextChar = String.fromCharCode(nextChar.charCodeAt(0)+1);
} else {
i++;
nextChar = String.fromCharCode(strArr[i].charCodeAt(0)+1);
}
}
return missingChars.join('') === '' ? undefined : missingChars.join('') ;
}
console.log(fearNotLetter("ab"));
Here is what I use:
function fearNotLetter(str) {
var firstLtrUnicode = str.charCodeAt(0),
lastLtrUnicode = str.charCodeAt(str.length - 1);
var holder = [];
for (var i=firstLtrUnicode; i<=lastLtrUnicode; i++) {
holder.push(String.fromCharCode(i));
}
var finalStr = holder.join('');
if ( finalStr === str ) { return undefined; }
else { return holder.filter( function(letter) {
return str.split('').indexOf(letter) === -1;
}).join(''); } }
Try this:
function fearNotLetter(str) {
var alp = ('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ').split(''), i;
for (i = alp.indexOf(str.charAt(0)); i < str.length; i++) {
if (str.split('').indexOf(alp[i]) === -1) {
return alp[i];
}
}
return undefined;
}
fearNotLetter('bcd');
Here's my solution, which i find to be quite easy to interpret:
function fearNotLetter(str) {
var missingLetter;
for (var i = 0; i < str.length; i++) {
if (str.charCodeAt(i) - str.charCodeAt(i-1) > 1) {
missingLetter = String.fromCharCode(str.charCodeAt(i) - 1);
}
}
return missingLetter;
}
I just did this challenge. I am a beginner to Javascript so this was my approach, very simple, sometimes you don't have to use the methods they provide but they also help. I hope you can understand it.
function fearNotLetter(str) {
var alphabet= "abcdefghijlmnopqrstuvwxyz";
var piece =alphabet.slice(0, str.length+1);
for(var i=0; i < piece.length; i++ ){
if(str.charCodeAt(0) != 97){
return undefined;
}
else if(str.indexOf(piece[i])===-1){
return piece[i];
}
}// for loop
}
fearNotLetter("abce");// It will return d
fearNotLetter("xy");//It will return undefined
fearNotLetter("bce");//It will return undefined
function fearNotLetter(str) {
//transform the string to an array of characters
str = str.split('');
//generate an array of letters from a to z
var lettersArr = genCharArray('a', 'z');
//transform the array of letters to string
lettersArr = lettersArr.join('');
//substr the a to z string starting from the first letter of the provided
string
lettersArr = lettersArr.substr(lettersArr.indexOf(str[0]), str.length);
//transform it again to an array of letters
lettersArr = lettersArr.split('');
//compare the provided str to the array of letters
for(var i=0; i<lettersArr.length;i++){
if(str[i] !== lettersArr[i])
return lettersArr[i];
}
return undefined;
}
function genCharArray(charA, charZ) {
var a = [], i = charA.charCodeAt(0), j = charZ.charCodeAt(0);
for (; i <= j; ++i) {
a.push(String.fromCharCode(i));
}
return a;
}
fearNotLetter("bcd");
Here's my another answer in missing letters:
function fearNotLetter(str) {
var alphabet = 'abcdefghijklmnopqrstuvwxyz';
var first = alphabet.indexOf(str[0]);
var last = alphabet.indexOf(str[str.length-1]);
var alpha = alphabet.slice(first,last);
for(var i=0;i<str.length;i++){
if(str[i] !== alpha[i]){
return alpha[i];
}
}
}
console.log(fearNotLetter("abce"));
Overview:
const fearNotLetter = str => {
if(str.length < 26) {
return String.fromCharCode(
str.split("")
.map(x=> x.charCodeAt(0))
.sort((a,b) => a-b)
.find((x,i,a) => a[i+1]-x > 1) + 1
);
}
}
1 liner:
const fearNotLetter = str => str.length < 26 ? String.fromCharCode(str.split("").map(x=> x.charCodeAt(0)).sort((a,b) => a-b).find((x,i,a) => a[i+1]-x > 1) + 1) : undefined;
function fearNotLetter(str) {
var allChars = "";
var notChars = new RegExp("[^" + str + "]","g");
for (var i = 0; allChars[allChars.length - 1] !== str[str.length - 1]; i++)
allChars += String.fromCharCode(str[0].charCodeAt(0) + i);
return allChars.match(notChars) ? allChars.match(notChars).join("") : undefined;
}
function fearNotLetter(str) {
let alphabet = "abcdefghijklmnopqrstuvwxyz"
let startingPoint = alphabet.indexOf(str[0]);
let leaterNotMatch = alphabet.slice(startingPoint)
console.log(startingPoint)
for(let i = 0; i<str.length; i +=1){
if(str[i] != leaterNotMatch[i]){
return leaterNotMatch[i];
}
}
}
let result = fearNotLetter("abcdefghjklmno");
console.log(result)
function findMissingLetter(letters) {
const alphabet = ['A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
let otherAlphabet = [];
if (letters[0] !== letters[0].toUpperCase()) {
otherAlphabet = alphabet.map(item => item.toLowerCase());
} else {
otherAlphabet = alphabet;
}
const firstIndex = otherAlphabet.findIndex((aplhabetEl) => {
return aplhabetEl === letters[0];
});
const lastIndex = otherAlphabet.findIndex((aplhabetEl) => {
return aplhabetEl === letters[letters.length - 1];
});
const sliceAlphabet = otherAlphabet.slice(firstIndex, lastIndex + 1);
let result = '';
for (let i = 0; i < letters.length; i++) {
if (letters[i] !== sliceAlphabet[i]) {
result += sliceAlphabet[I];
}
}
return result.slice(0, 1);
}
You can also solve this question by using a map which we will call seen. For every letter, we will add it to our seen map. Then we will loop through the alphabet checking if we have come across that letter in our seen map.
If we have come across that letter in our seen map, then we will use a boolean flag foundFirstLetter and set that to true. Then inside another conditional foundFirstLetter, we can check if the letter is missing and if it is we can just return the letter because we know it's missing.
This solution works, but it isn't ideal because it uses more space (because of our seen map), unlike the other solutions.
const findMissingLetter = (array) => {
const convertUpperCase = array[0] === array[0].toUpperCase() ? true : false;
const alphabet = "abcdefghijklmnopqrstuvwxyz";
const seen = {};
let foundFirstLetter = false;
// add the words we have run across to our seen map
for(const letter of array){
seen[letter.toLowerCase()] = true;
}
// loop through our alphabet checking if letter is in our map. If we find the first letter, then that means
// if we don't find the next letter in our map then it's missing.
for(const letter of alphabet){
if(seen.hasOwnProperty(letter)){
foundFirstLetter = true;
}
if(foundFirstLetter){
if(!seen.hasOwnProperty(letter)){
if(convertUpperCase){
return letter.toUpperCase();
} else {
return letter;
}
}
}
}
}
function fearNotLetter(str) {
var string = array. join("");
for (var i = 0; i < string. length; i++) {
if (string. charCodeAt(i + 1) - string. charCodeAt(i) != 1) {
return String. fromCharCode(string. charCodeAt(i) + 1);
}
}
return undefined
}

Categories

Resources