Longest chain of letters in word JavaScript - javascript

I need to write a program that is find longest chain of letters in a word and displays it in a console.log with their length. Example aaaAAAAdddeess - console.log( 'AAAA' ,4 ). Program must be in JavaScript and must distinguish capital letters. I`ve tried something like
const word = 'aaadddAAAwwwweee'
let newWord = ' '
for (let i = 0; i < word.length; i++) {
if (word[i] === word[i + 1]) {
newWord += word[i] + word[i + 1]
i++
}
}
console.log(newWord, newWord.lenght)

You can split the word to letters and check each letter with next one. Then push current sequence in an array, it will be current max sequence. Each iteration check the size of current longest sequnece with max sequence.
const word = 'aaadddAAAwwwweee'
let lettersArr = word.split('');
let currentSequence = [];
let maxSequence = [];
for (let index = 0; index < lettersArr.length; index++) {
let element = lettersArr[index];
currentSequence = [element];
for (let i = index + 1; i < lettersArr.length; i++) {
if (lettersArr[index] == lettersArr[i]) {
currentSequence.push(lettersArr[index]);
} else {
break;
}
}
if (currentSequence.length > maxSequence.length) {
maxSequence = currentSequence;
}
}
let newWord = maxSequence.join('');
console.log(newWord, newWord.length);

Related

Check if my array has consecutive similar letters randomly generated

I have to generate 200 random letters (function has to do it) separated by commas. It doesn't matter if they are repeated but it must not be consecutively. If they are consecutive, I have to replace it with a new letter generated randomly by my function. I am new to programming. I also cannot modify my function as a constraint.
For the sake of the output, I am generating 10 numbers instead of 200.
This is my working code. I just can't manage to add a new random letter where I deleted a duplicate.
const characters = 'abcdefghijklmnopqrstuvwxyz';
function getRandomLetter() { return characters.charAt(Math.floor(Math.random() * characters.length)).toUpperCase(); }
var randomLetters = [];
for (let j = 0; j < 10; j++) { randomLetters [j] = getRandomLetter(); }
document.write("10 random letters: ", randomLetters );
let uniqueArr = [];
for(let i of randomLetters) {
if(uniqueArr.indexOf(i) === -1) {
uniqueArr.push(i);
}
}
document.write("10 random letters without duplicates: ", uniqueArr);
In order to increase the chance of consecutive letters, I removed most of the letters from the const of characters.
const characters = 'abcdef';
function getRandomLetter() { return characters.charAt(Math.floor(Math.random() * characters.length)).toUpperCase(); }
var randomLetters = [];
for (let j = 0; j < 10; j++) {
randomLetters [j] = getRandomLetter();
while(randomLetters [j] == randomLetters [j-1]){
console.log("consecutive");
randomLetters [j] = getRandomLetter();
}
}
document.write("10 random letters: ", randomLetters );
let uniqueArr = [];
for(let i of randomLetters) {
if(uniqueArr.indexOf(i) === -1) {
uniqueArr.push(i);
}
}
document.write("10 random letters without duplicates: ", uniqueArr);
So if it can not be the same as the previous write your random code to keep generating until it does not match
const characters = Array.from('abcdefghijklmnopqrstuvwxyz');
function getRandomLetter(last) {
const val = characters[Math.floor(Math.random() * characters.length)].toUpperCase();
if (last === val) return getRandomLetter(last);
return val;
}
var randomLetters = [];
for (let j = 0; j < 10; j++) {
randomLetters[j] = getRandomLetter(randomLetters[j - 1]);
}
console.log(randomLetters.join(','));
Use a generator function:
function* randomChars(n) {
let lastChar, c
while(n>0) {
do {
c = String.fromCharCode((Math.random()*26|0)+65)
} while (c===lastChar)
yield (n--, lastChar=c)
}
}
console.log([...randomChars(200)].join())

Character with longest consecutive repetition

i think i have wirtten the correct code for the problem only one thing and it that i return the first longest sequence how can i alter that to return the last maximum sequence?
an example from codewars editor :
for input '00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'
Expected: ['c', 19], instead got: ['0', 19]
here is my code:
function longestRepetition(s) {
var count = 0;
var temp = s.charAt(0);
var arr = [];
for (var i = 0; i < s.length; i++) {
if (temp === s.charAt(i)) {
count++
temp = s.charAt(i)
}
else {
temp = s.charAt(i);
arr.push(count)
count = 1;
}
if(i==s.length-1)
arr.push(count);
}
if(arr.length>0)
{
var Max=arr[0]
for(var i=0;i<arr.length;i++)
{
if(Max<=arr[i])
Max=arr[i];
}
}
else var Max=0;
var mindex=arr.indexOf(Max);
return [s.charAt(mindex),Max]
}
I think this would be easier with a regular expression. Match any character, then backreference that character as many times as you can.
Then, you'll have an array of all the sequential sequences, eg ['000', 'aaaaa']. Map each string to its length and pass into Math.max, and you'll know how long the longest sequence is.
Lastly, filter the sequences by those which have that much length, and return the last item in the filtered array:
function longestRepetition(s) {
const repeatedChars = s.match(/(.)\1*/g);
const longestLength = Math.max(...repeatedChars.map(str => str.length));
const longestChars = repeatedChars.filter(str => str.length === longestLength);
return [longestChars.pop(), longestLength];
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
The issue in your code is that minindex is an index in your arr, but that index has nothing to do with s. So s.charAt(minindex) makes no sense. You should maintain for which character you had found the count. For instance you could push in arr both the count and the corresponding character (as a subarray with two values). Then the rest of your code would only need little modification to make it work.
Applying this idea to your code without changing anything else, we get this:
function longestRepetition(s) {
var count = 0;
var temp = s.charAt(0);
var arr = [];
for (var i = 0; i < s.length; i++) {
if (temp === s.charAt(i)) {
count++
temp = s.charAt(i) // Not necessary: was already equal
}
else {
arr.push([temp, count]); // <--- pair, BEFORE changing temp
temp = s.charAt(i);
count = 1;
}
if(i==s.length-1)
arr.push([temp, count]); // <---
}
if(arr.length>0)
{
var Max=arr[0]; // <-- Max is now a pair of char & count
for(var i=0;i<arr.length;i++)
{
if(Max[1]<arr[i][1]) // Comparison changed to just less-than
Max=arr[i];
}
}
else Max=[null, 0]; // Must be a pair here also
return Max; // Just return the pair
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
But you can do the same with less code:
function longestRepetition(s) {
let result = [null, 0]; // pair of character and count
for (var i = 0; i < s.length; null) {
let start = i++;
while (i < s.length && s[i] === s[start]) i++; // Find end of series
if (i - start > result[1]) result = [s[start], i - start];
}
return result;
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
The solution below answers the question with O(n) runtime:
function longestRepetition(s) {
let count = s.length > 0 ? 1 : 0
let char = s.length > 0 ? s[0] : ''
for (let string_i = 0; string_i < s.length - 1; string_i += 1) {
// keep track of current_char
let current_char = s[string_i]
let next_char = s[string_i + 1]
// while the next char is same as current_char
let tracker = 1
while (current_char === next_char) {
// add one to tracker
tracker += 1
string_i += 1
next_char = s[string_i + 1]
}
// if tracker greater than count
if (tracker > count) {
// returned char = current char
// count =tracker
count = tracker;
char = current_char;
}
}
return [char, count]
}
console.log(longestRepetition("bbbaaabaaaa"))//, ["a",4]

Counting the number of duplicates with nested loops. How to escape from comparing two chars with the same index

Function that will return the count of distinct case-insensitive alphabetic characters and numeric digits that occur more than once in the input string.
"abcde" -> 0 # no characters repeats more than once
"indivisibility" -> 1 # 'i' occurs six times
rs twice
The problem is that each iteration loops meet on the same char and compare it. How can I avoid it?
function duplicateCount(text){
var texT = text.toLowerCase();
var count = 0;
var total = 0;
for(var i = 0; i < texT.length; i++ ){
var char = texT[i];
if(count > 1){
total = total + 1;
}
for ( var j = 0; j < texT.length; j++){
var char2 = texT[j];
if(char === char2){
count = count + 1;
}
}
}
return total;
}
duplicateCount('kBHhJkj8l8');
function duplicateCount(text){
var texT = text.toLowerCase();
const obj = {};
for(var i = 0; i < texT.length; i++ ){
if(obj[texT[i]]) {
obj[texT[i]] += 1;
}
else {
obj[texT[i]] = 1;
}
}
let total = 0;
Object.keys(obj).forEach(key => {
if(obj[key] != 1){
total += 1;
}
})
return total;
}
console.log(duplicateCount('kBHhJkj8l8'));
Use a hash to keep track of the visited chars, and skip the comparison if you already have a duplicate char (at least 2):
function duplicateCount(text){
text = text.toLowerCase();
const occurrences = {};
for (let char of text) {
if (occurrences[char] === 2) continue; // skip comparison
occurrences[char] = ~~ occurrences[char] + 1;
}
return Object.values(occurrences)
.filter((occurrence) => occurrence > 1)
.length;
}
console.log(duplicateCount('kBHhJkj8l88888'));

Find duplicate phrases (not just words) in array

Let's say I have an array:
[
"I want **a dog**",
"**A dog** is here",
"Pet **a dog**",
"A **red cat**",
"**red cat** is cute"
...
]
How do I figure out what the duplicate phrases are, not just words?
For example, I'd like "a dog" and "red cat" to be returned.
Most existing posts I found are only about getting individual words, not phrases (multiple words).
You're giving us too little information. I'm assuming you're splitting by spaces. ES6 to the rescue :). Sets have O(1) lookup for when you're looking for repeated phrases.
edit: Just realized that you can cut down space complexity by a ton with some small modifications. If you want me to do that, give me a shoutout.
const buildAllPhrases = sentence => {
const splitSentence = sentence.split(" ")
const phraseSize = splitSentence.length
const allPhrases = []
for (let i = phraseSize; i > 0; i--) {
for (let y = 0; y + i <= phraseSize; y++) {
allPhrases.push(splitSentence.slice(y, y + i))
}
}
return allPhrases.map(phrase => phrase.join(" "))
}
const findRepeats = sentences => {
const allPhrases = new Set()
const repeatedPhrases = new Set()
let phrases
sentences.forEach(phrase => {
phrases = buildAllPhrases(phrase)
phrases.forEach(subPhrase => {
if (allPhrases.has(subPhrase)) {
repeatedPhrases.add(subPhrase)
} else {
allPhrases.add(subPhrase)
}
})
})
return [...repeatedPhrases]
}
const sample = [
"I want **a dog**",
"**A dog** is here",
"Pet **a dog**",
"A **red cat**",
"**red cat** is cute"
]
findRepeats(sample)
//['dog**', '**a dog**', '**a', '**red cat**', '**red', 'cat**', 'is']
This is not final version of the javascript function, and it can be optimized further. Few changes may also be required, but it can be starter for your requirement.
function GetPhrases(stringsArray) {
//Array to split your string into words.
var jaggedArray = [];
//Array to keep indexes of strings where 2 matching words are found together.
var newArray = [];
var phrases = [];
//Loop through your array
for (var ic = 0; ic < stringsArray.length; ic++) {
//Convert every item to array of strings
var items = (stringsArray[ic]).split(" ");
for (var it = 0; it < items.length; it++)
items[it] = items[it].toLowerCase();
//Push the array of words to main array
jaggedArray.push(items);
}
//console.log(jaggedArray);
// Loop through the main array
for (var iLoop = 0; iLoop < jaggedArray.length; iLoop++) {
// For every item in main array, loop through words in that item.
for (var ik = 0; ik < jaggedArray[iLoop].length; ik++) {
var currentWord = jaggedArray[iLoop][ik];
// For every word, check its existence in the main array in all items coming after current item.
for (var il = iLoop + 1; il < jaggedArray.length; il++) {
// Find the index in the string.
var indexOfFind = jaggedArray[il].indexOf(currentWord);
if (indexOfFind > 0) {
// if matching index is more than 0, find if the word before this word also matches.
var indexofPrevWord = jaggedArray[il].indexOf(jaggedArray[iLoop][ik - 1]);
if ((indexofPrevWord >= 0) && (indexofPrevWord == (indexOfFind - 1)))
if (newArray.indexOf(il + " - " + iLoop) < 0)
newArray.push(il + " - " + iLoop);
// if matching index is more than 0, find if the word after this word also matches.
var indexofNextWord = jaggedArray[il].indexOf(jaggedArray[iLoop][ik + 1]);
if (indexofNextWord >= 0 && (indexofNextWord == (indexOfFind + 1)))
if (newArray.indexOf(il + " - " + iLoop) < 0)
newArray.push(il + " - " + iLoop);
}
else if (indexOfFind = 0) {
// if matching index is more than 0, find if the word after this word also matches.
var indexofNewWord = jaggedArray[il].indexOf(jaggedArray[iLoop][ik + 1]);
if (indexofNewWord >= 0 && (indexofNewWord == (indexOfFind + 1)))
if (newArray.indexOf(il + " - " + iLoop) < 0)
newArray.push(il + " - " + iLoop);
}
}
}
}
//newArray will store indexes of those string arrays in jagged array which has a matching sequence of atleast 2 words.
//console.log(newArray);
//Loop through newArray
for (var itl = 0; itl < newArray.length; itl++) {
var item = newArray[itl];
var values = item.split(" - ");
var firstArrayItem = jaggedArray[values[0]];
var secondArrayItem = jaggedArray[values[1]];
var phraseStartPoint = [];
//for every word in firstItem
for (var iy = 0; iy < firstArrayItem.length - 1; iy++) {
var t = iy + 1;
// check if that word and next word exist in second array
if (secondArrayItem.toString().indexOf(firstArrayItem[iy] + "," + firstArrayItem[t]) >= 0) {
// if they do exist, get the indexes of these and store in local array, if they are not there, since we do not want repeating words later.
if (phraseStartPoint.indexOf(iy) < 0)
phraseStartPoint.push(iy);
if (phraseStartPoint.indexOf(t) < 0)
phraseStartPoint.push(t);
}
}
var str = "";
// Prepare the phrase from the local array and push into phrases array, if it not exists there.
for (var ifinalLoop = 0; ifinalLoop < phraseStartPoint.length; ifinalLoop++) {
str = str + firstArrayItem[phraseStartPoint[ifinalLoop]] + " ";
}
if (phrases.indexOf(str) < 0)
phrases.push(str);
}
return phrases;
}
var stringsArray = [
"I want a dog",
"A dog is here",
"Pet a dog is cute",
"A red cat is here",
"red cat is cute"
];
var result = GetPhrases(stringsArray);
// Print the phrases array.
for (var iPhrase = 0; iPhrase < result.length; iPhrase++) {
console.log(result[iPhrase]);
}
with regex you can detect duplicates in strings.
According to this regex:
(?:.*?)(\b\w.{3,}\b)(?:.*?)(\1) ,
it only works if you're looking for twice the same pattern.
note: you can replace 3 in {3,} by any other integer and see the changes.
This paramater contrains the minimal string lenght you're looking for twice.

longest substring of non repeating characters javascript

The problems asks "given a string, find the longest non-repeating sub-string without repeating characters". I am a little stumped why returning my code is not working for the string "dvdf" for example. Here is my code :
function lengthOfLongestSubstring(check) {
var letters = check.split("");
var max = 0;
var result = [];
for (var i = 0; i < letters.length; i++) {
var start = i
if (result.indexOf(letters[i]) === -1) {
result.push(letters[i])
} else {
i = i - 1
result = []
}
if (max === 0 || max < result.length) {
max = result.length
}
}
return max
}
This implementation gives the correct result for "dvdf".
It adds characters to current_string while there is no duplicate. When you find a duplicate cut current_string to the point of the duplicate. max is the max length current_string had at any time. This logic seems correct to me so I think it's correct.
function lengthOfLongestSubstring(string) {
var max = 0, current_string = "", i, char, pos;
for (i = 0; i < string.length; i += 1) {
char = string.charAt(i);
pos = current_string.indexOf(char);
if (pos !== -1) {
// cut "dv" to "v" when you see another "d"
current_string = current_string.substr(pos + 1);
}
current_string += char;
max = Math.max(max, current_string.length);
}
return max;
}
lengthOfLongestSubstring("dvdf"); // 3
The value of current_string in each round is "", "d", "dv", "vd", "vdf".
By replacing the result array with a map storing the last index for each encountered character, you can modify the loop body to jump back to one after the last index of an identical character and continue your search from there instead of just restarting from the current position via currently i = i - 1 which fails in cases such as 'dvdf':
Below is your code with changes to accommodate a map in place of an array:
function lengthOfLongestSubstring(check) {
var letters = check.split("");
var max = 0;
var result = new Map();
var start = 0;
for (var i = 0; i < letters.length; i++) {
if (!result.has(letters[i])) {
result.set(letters[i], i);
} else {
i = result.get(letters[i]);
result.clear();
}
if (max < result.size) {
max = result.size;
}
}
return max;
}
// Example:
console.log(lengthOfLongestSubstring("dvdf")); // 3
Here's a solution using Sliding window and HashMap.
var lengthOfLongestSubstring = function(str) {
if (!!!str.length || typeof str !== 'string') return 0;
if (str.length == 1) return 1;
let hashTable = {};
let longestSubstringLength = 0;
let start = 0;
for (let i = 0; i < str.length; i++) {
if (hashTable[str[i]] !== undefined && hashTable[str[i]] >= start) {
start = hashTable[str[i]] + 1;
}
hashTable[str[i]] = i;
longestSubstringLength = Math.max(longestSubstringLength, (i - start + 1))
}
return longestSubstringLength;
}
I figured out an easier solution:
function longestSubstring(str) {
let left = 0;
let max = 0;
let result = new Set();
for (let r = 0; r < str.length; r++) {
//The code will check for an existing item on the set
// If found, all the previously saved items will be deleted
// the set will return to being empty
while (result.has(str[r])) {
result.delete(str[left]);
left += 1;
}
result.add(str[r]);
max = Math.max(max, r - left + 1);
}
console.log(result);
return max;
}
console.log(longestSubstring('abcabccbc')); //3
Today (January 7th, 2021) this was the Leetcode question of the day. I initially used a solution very similar to the selected answer. Performance was okay but after reviewing the answer solution documentation I rewrote my answer using the sliding window technique (examples were only in Java and Python) since I was curious about how much of a performance improvement this would result in. It is slightly more performant (144ms versus 160ms) and has a lower memory footprint (42mb versus 44.9mb):
function lengthOfLongestSubstring(s: string): number {
let stringLength = s.length;
let maxLength = 0;
const charMap = new Map();
let pos = 0;
for (let i = 0; i < stringLength; i++) {
if (charMap.has(s[i])) {
pos = Math.max(charMap.get(s[i]), pos);
}
maxLength = Math.max(maxLength, i - pos + 1);
charMap.set(s[i], i + 1);
}
return maxLength;
}
console.log(lengthOfLongestSubstring("dvdf"));
Try this:
function lengthOfLongestSubstring (str) {
const map = new Map();
let max = 0;
let left = 0;
for (let right = 0; right < str.length; right++) {
const char = str[right];
if (map.get(char) >= left) left = map.get(char) + 1;
else max = Math.max(max, right - left + 1);
map.set(char, right);
}
return max;
}
You can try this:
function lengthOfLongestSubstring(str) {
let longest = "";
for (let i = 0; i < str.length; i++) {
if (longest.includes(str[i])) {
return longest.length
} else {
longest += str[i];
}
}
return longest.length;
}
console.log(lengthOfLongestSubstring("abcabcbb"));
console.log(lengthOfLongestSubstring("bbbbb"));
console.log(lengthOfLongestSubstring("abcdef"));
console.log(lengthOfLongestSubstring(""));
reset i to i -1 is incorrect. you need another loop inside the for loop. you try something like this (i didn't check the index carefully).
function lengthOfLongestSubstring(check){
var letters = check.split("");
var max = 0;
for (var i = 0; i < letters.length; i++) {
var result = [];
var j = i;
for(;j < letters.length; j++) {
if (result.indexOf(letters[j]) === -1) {
result.push(letters[j]);
} else {
break;
}
}
if(j - i > max) {
max = j - i;
}
}
return max;
}
You can try sliding window pattern to solve this problem.
function lengthOfLongestSubstring(str) {
let longest = 0;
let longestStr = "";
let seen = {};
let start = 0;
let next = 0;
while (next < str.length) {
// Take current character from string
let char = str[next];
// If current character is already present in map
if (seen[char]) {
// Check if start index is greater than current character's last index
start = Math.max(start, seen[char]);
}
// If new substring is longer than older
if (longest < next - start + 1) {
longest = next - start + 1;
// Take slice of longer substring
longestStr = str.slice(start, next + 1);
}
// Update current characters index
seen[char] = next + 1;
// Move to next character
next++;
}
console.log(str, "->", longestStr, "->", longest);
return longest;
}
lengthOfLongestSubstring("dvdfvev");
lengthOfLongestSubstring("hello");
lengthOfLongestSubstring("1212312344");
Find Longest Unique Substring using Map Method
var str = "aaabcbdeaf";
var start = 0;
var map = new Map();
var maxLength = 0;
var longStr = '';
for(next =0; next< str.length ; next++){
if(map.has(str[next])){
map.set(str[next],map.get(str[next])+1);
start = Math.max(start,map.get(str[next]));
}
if(maxLength < next-start+1){
maxLength = next-start+1;
longStr = str.slice(start,next+1);
}
map.set(str[next],next);
}
console.log(longStr);
You can try something like that:
function maxSubstring(s) {
const array = []
const lengthS = s.length
const pusher = (value) => {
if (value !== '') {
if (array.length > 0) {
if (array.indexOf(value) === -1) {
array.push(value)
}
} else {
array.push(value)
}
}
}
pusher(s)
for (const [index, value] of s.split('').entries()) {
let length = lengthS
let string = s
const indexO = s.indexOf(value)
pusher(value)
while (length > indexO) {
pusher(string.slice(index-1, length + 1))
length = --length
}
string = s.slice(index, lengthS)
}
array.sort()
return array.pop()
}
console.log(maxSubstring('banana'))
console.log(maxSubstring('fgjashore'))
console.log(maxSubstring('xyzabcd'))
Find Longest unique substring without using MAP(). Just simple slice().
The same can be used to return longest unique string.
Just replace "return max => return str"
const string = "dvdf";
var lengthOfLongestSubstring = function() {
if(string.length == 1) return 1;
if(string.length == 0) return 0;
let max = 0,i = 0, str = "";
while(i < string.length){
const index = str.indexOf(string.charAt(i));
if(index > -1) {
// s = "fiterm".slice(1,4) => ite
str = str.slice(index + 1, string.length);
}
str += string.charAt(i);
max = Math.max(str.length, max);
i++;
}
return max;
};
Logest unqiue substring:
function lengthOfLongestSubstring(s) {
if(s.length < 2) {
return s.length;
}
let longestLength = 1;
let currentStr = '';
for(let i=0 ; i < s.length ; i++){
if(currentStr.includes(s.charAt(i))){
let firstSeen = currentStr.indexOf(s.charAt(i));
currentStr = currentStr.substring(firstSeen+1,currentStr.length);
}
currentStr += s.charAt(i);
longestLength = Math.max(currentStr.length,longestLength);
}
return longestLength;
};
One liner with reduce method.
const subStrOfUniqueChar = str => [...str].reduce((p,c) => ( p.includes(c) ? (p += c, p.substr(p.indexOf(c)+1)) : p += c),'');
console.log(subStrOfUniqueChar('dvdf').length);
function lengthOfLongestSubstring(s: string): number {
const arr = s.split("");
let longest = 0;
const set: Set<string> = new Set();
for (let i = 0; i < arr.length; i++) {
set.add(arr[i]);
let tryIndex = i + 1;
while (arr[tryIndex] && !set.has(arr[tryIndex])) {
set.add(arr[tryIndex]);
tryIndex++;
}
if (set.size > longest) {
longest = set.size;
}
set.clear();
}
return longest;
}
I wanted to toss my hat in this ring because I feel like I've found a pretty creative solution to this. No if/else blocks are needed as the substring.indexOf() will attempt to find the matching string character in the array and delete the indexes of the array up to, and including, the match (+1). If an indexOf() call finds no match it will return a -1, which added to +1 becomes a .splice(0,0) which will remove nothing. The final Math check factors in the last character addition in the loop to determine which outcome is higher.
const findSubstring = string => {
let substring = [];
let maxCount = 0;
for (let i = 0; i < string.length; i++) {
maxCount = Math.max(substring.length, maxCount);
substring.splice(0, substring.indexOf(string[i]) + 1);
substring.push(string[i]);
}
maxCount = Math.max(substring.length, maxCount);
return maxCount;
}
uses sliding window concept
function lengthOfLongestSubstring(s) {
var letters = s.split("");
var subStr = "";
var result = [];
var len = 0;
let maxLen = 0;
for (var i = 0; i < letters.length; i++) {
const position = result.indexOf(letters[i]);
if (position === -1) {
result.push(letters[i]);
len += 1;
} else if (letters[i]) {
result = result.splice(position + 1);
len = result.length + 1;
result.push(letters[i]);
}
maxLen = len > maxLen ? len : maxLen;
}
return maxLen;
}
console.log(lengthOfLongestSubstring(" "));
Sliding Window Technique O(n)
you can use hash or Map in
loop through string char
Maintain dictionary of unique char
if char exist in memory take clear hash update the count in longest variable and clear count
start from first repeated char + 1 again.
var lengthOfLongestSubstring = function(s) {
if(s.length<2) return s.length;
let longest = 0;
let count=0;
let hash={}
for (let i = 0; i < s.length; i++) {
//If char exist in hash
if(hash[s[i]]!=undefined){
i=hash[s[i]];
hash={}
longest = Math.max(longest, count);
count = 0;
}else{
hash[s[i]]=i
count = count+1;
}
}
return Math.max(longest, count);
};
console.log(lengthOfLongestSubstring("abcabcbb"))
console.log(lengthOfLongestSubstring("au"))

Categories