Given two strings s1 and s2 consisting of lowercase English alphabets, the task is to count all the pairs of indices (i, j) from the given strings such that s1[i] = s2[j] and all the indices are distinct i.e. if s1[i] pairs with some s2[j] then these two characters will not be paired with any other character.
Input: s1 = 'abcd', s2 = 'aad'
Output: 2
Input: s1 = 'geeksforgeeks', s2 = 'platformforgeeks'
Output: 8
I tried to like this:
function getSameCount(str, str2) {
var o = {},
o2 = {};
for (var i = 0; i < str.length - 1; i++) {
if (str[i] in o) {
o[str[i]] = parseInt(o[str[i]] + 1)
} else {
o[str[i]] = 0
}
}
console.log(o);
for (var i = 0; i < str2.length - 1; i++) {
if (str[i] in o2) {
o2[str[i]] = parseInt(o2[str[i]] + 1)
} else {
o2[str[i]] = 0
}
}
console.log(o2);
}
getSameCount('abcd', 'aad')
Use for..in loop and includes method
var s1 = "abcd";
var s2 = "aad";
function match(s1, s2) {
var count = 0;
for(let i in s1) {
s2.includes(s1[i]) ? count++ : false;
}
return count;
}
console.log(match(s1,s2));
We can convert the second input string to an array, then the next step is to iterate over the first input string and find a match in the second input string's character array.
If a match is found, increment the counter and remove that character from the second input string's character array so that it is not considered in the next match:
//Solution:
function getSameCount(str1, str2) {
let count = 0;
const obj = str2.split("");
for(str of str1){
let idx = obj.findIndex(s => s === str);
if(idx >= 0){
count++;
obj.splice(idx, 1);
}
}
return count;
}
//Test:
console.log(getSameCount("abcd", "aad"));
console.log(getSameCount("geeksforgeeks", "platformforgeeks"));
console.log(getSameCount("aad", "abcd"));
console.log(getSameCount("platformforgeeks", "geeksforgeeks"));
You can create a custom method on the array and find the number of characters which are common in all the words. Below steps are list of procedure to find the common characters in all the string
Create a prototype method on Array , findCommonWord in this case.
This method accepts an array of string, so input will be like
[ "abcd", "aad","geeksforgeeksda","platdformforgeeks"].findCommonWord()
First step is to modify the input, to remove duplicate characters from a string using Set then sort it by ascending order of the length of string. This is because number of loop will be least if we have to find common character , that also have to present in string with least length.
Then create a new array with out the first string and split the first string. split will create a new array and iterate over it and check if this character is present in rest of the string.
var s1 = "abcd",
s2 = "aad",
s3 = "geeksforgeeksda",
s4 = "platdformforgeeks";
Array.prototype.findCommonWord = function() {
let tempArray = this.map(function(item) {
return [...new Set(item.split(''))].join('');
}).sort(function(a, b) {
return a.length - b.length
})
let count = 0;
let firstElm = tempArray[0].split('');
let restElem = tempArray.splice(1);
let countObject = {}
for (let i = 0; i < firstElm.length; i++) {
let z = findIfIncludes(restElem, firstElm[i]);
if (z.length === restElem.length) {
countObject[firstElm[i]] = 1;
} else {
countObject[firstElm[i]] = 0
}
}
function findIfIncludes(arr, char) {
return arr.filter(item => item.includes(char))
}
console.log(countObject)
let totalCount = 0;
for (let keys in countObject) {
if (countObject[keys] > 0) {
totalCount += 1;
}
}
return totalCount;
};
console.log([s1, s2, s3, s4].findCommonWord());
function numberOfSameChars(s1, s2) {
let obj = {};
let counter = 0;
for (let i=0; i<s1.length; i++){
if(s1[i] in obj) {
obj[s1[i]]++;
} else {
obj[s1[i]] = 1;
}
}
for (let i=0; i<s2.length; i++) {
if(s2[i] in obj && obj[s2[i]] > 0) {
obj[s2[i]]--;
counter++;
}
}
return counter;
}
Try this code:
function countMatch(s1,s2){
var count = 0;
while(s1.length && s2.length){
if(s2.includes(s1.charAt(0))){
count++;
s2 = s2.replace(s1.charAt(0),"");
s1 = s1.slice(1);
}
else {
s1 = s1.slice(1);
}
}
return count;
}
console.log(countMatch("abcd","aad"));
//2
I used objects to do this, and I was kind of curious about there being another way, as I wanted to take an algorithmic approach as well, but whatever works works.
Anyways, here's the code:
function commonCharacterCount(s1, s2) {
let string1Counter = {};
let string2Counter = {};
let commonCount = 0;
for(let i = 0; i < s1.length; i++){
if(!string1Counter.hasOwnProperty(s1[i])){
string1Counter[s1[i]] = 0;
}
string1Counter[s1[i]]++;
}
for(let i = 0; i < s2.length; i++){
if(!string2Counter.hasOwnProperty(s2[i])){
string2Counter[s2[i]] = 0;
}
string2Counter[s2[i]]++;
}
for(let key in string1Counter){
if(string2Counter.hasOwnProperty(key)){
if(string1Counter[key] < string2Counter[key]){
commonCount += string1Counter[key];
}
else{
commonCount += string2Counter[key];
}
}
}
return commonCount;
}
The logic is basically to just save all of the characters of each string and their count,check for similarities, and compare the count of common characters. Whichever has the fewer amount of common characters will be the amount shared by both.
O(3N) time complexity, O(2N) space complexity (because of the stored objects).
I guess I can also do "delete object" but seems redundant on just an algorithm IDE because it's not like it's running on a server for any extended period of time.
function commonSameCount(s1, s2) {
var s1Array = s1.split("");
var s2Array = s2.split("");
var count = 0;
let index = 0;
s1Array.filter(s1 => {
index = s2Array.findIndex(s2 => s2 == s1);
if(index >= 0){
count++;
s2Array.splice(index, 1);
}
});
return count;
}
A simple solution using Regex:
index.js
function getSameCount(s1,s2) {
for (let i in s2) {
s1 = s1.replace(s2[i], "1")
}
const result = s1.replace(/[^1]/g, '').length
return result
}
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("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"))
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))
So I tried looking for this in the search but the closest I could come is a similar answer in several different languages, I would like to use Javascript to do it.
The problem is I have an arbitrary string that I would like to return the first non repeating character. EX: 'aba' -> would return b
'aabcbd' -> would return c.
This is what I have so far, just a simple for loop to start.
var someString = 'aabcbd';
var firstNonRepeatedCharacter = function(string) {
for(var i = 0; i < someString.length; i++){
}
};
http://jsfiddle.net/w7F87/
Not sure where to go from here
You can use the indexOf method to find the non repeating character. If you look for the character in the string, it will be the first one found, and you won't find another after it:
function firstNonRepeatedCharacter(string) {
for (var i = 0; i < string.length; i++) {
var c = string.charAt(i);
if (string.indexOf(c) == i && string.indexOf(c, i + 1) == -1) {
return c;
}
}
return null;
}
Demo: http://jsfiddle.net/Guffa/Se4dD/
If you're looking for the first occurrence of a letter that only occurs once, I would use another data structure to keep track of how many times each letter has been seen. This would let you do it with an O(n) rather than an O(n2) solution, except that n in this case is the larger of the difference between the smallest and largest character code or the length of the string and so not directly comparable.
Note: an earlier version of this used for-in - which in practice turns out to be incredibly slow. I've updated it to use the character codes as indexes to keep the look up as fast as possible. What we really need is a hash table but given the small values of N and the small, relative speed up, it's probably not worth it for this problem. In fact, you should prefer #Guffa's solution. I'm including mine only because I ended up learning a lot from it.
function firstNonRepeatedCharacter(string) {
var counts = {};
var i, minCode = 999999, maxCode = -1;
for (i = 0; i < string.length; ++i) {
var letter = string.charAt(i);
var letterCode = string.charCodeAt(i);
if (letterCode < minCode) {
minCode = letterCode;
}
if (letterCode > maxCode) {
maxCode = letterCode;
}
var count = counts[letterCode];
if (count) {
count.count = count.count + 1;
}
else {
counts[letterCode] = { letter: letter, count: 1, index: i };
}
}
var smallestIndex = string.length;
for (i = minCode; i <= maxCode; ++i) {
var count = counts[i];
if (count && count.count === 1 && count.index < smallestIndex) {
smallestIndex = count.index;
}
}
return smallestIndex < string.length ? string.charAt(smallestIndex) : '';
}
See fiddle at http://jsfiddle.net/b2dE4/
Also a (slightly different than the comments) performance test at http://jsperf.com/24793051/2
var firstNonRepeatedCharacter = function(string) {
var chars = string.split('');
for (var i = 0; i < string.length; i++) {
if (chars.filter(function(j) {
return j == string.charAt(i);
}).length == 1) return string.charAt(i);
}
};
So we create an array of all the characters, by splitting on anything.
Then, we loop through each character, and we filter the array we created, so we'll get an array of only those characters. If the length is ever 1, we know we have a non-repeated character.
Fiddle: http://jsfiddle.net/2FpZF/
Two further possibilities, using ECMA5 array methods. Will return undefined if none exist.
Javascript
function firstNonRepeatedCharacter(string) {
return string.split('').filter(function (character, index, obj) {
return obj.indexOf(character) === obj.lastIndexOf(character);
}).shift();
}
console.log(firstNonRepeatedCharacter('aabcbd'));
On jsFiddle
Or if you want a bit better performance, especially on longer strings.
Javascript
function firstNonRepeatedCharacter(string) {
var first;
string.split('').some(function (character, index, obj) {
if(obj.indexOf(character) === obj.lastIndexOf(character)) {
first = character;
return true;
}
return false;
});
return first;
}
console.log(firstNonRepeatedCharacter('aabcbd'));
On jsFiddle
I came accross this while facing similar problem. Let me add my 2 lines.
What I did is a similar to the Guffa's answer. But using both indexOf method and lastIndexOf.
My mehod:
function nonRepeated(str) {
for(let i = 0; i < str.length; i++) {
let j = str.charAt(i)
if (str.indexOf(j) == str.lastIndexOf(j)) {
return j;
}
}
return null;
}
nonRepeated("aabcbd"); //c
Simply, indexOf() gets first occurrence of a character & lastIndexOf() gets the last occurrence. So when the first occurrence is also == the last occurence, it means there's just one the character.
Here's a Solution using Regex to replace all repeating characters and then returning the first character.
function firstNonRepeat(str) {
// Sorting str so that all repeating characters will come together & replacing it with empty string and taking first character using substr.
var rsl = str.split('').sort().join('').replace(/(\w)\1+/g,'').substr(0,1);
if(rsl) return rsl;
else return 'All characters are repeated in ' + str;
}
console.log(firstNonRepeat('aaabcccdeeef'));
console.log(firstNonRepeat('aaacbdcee'));
console.log(firstNonRepeat('aabcbd'));
First of all, start your loop at 1, not 0. There is no point in checking the first character to see if its repeating, obviously it can't be.
Now, within your loop, you have someString[i] and someString[i - 1]. They are the current and previous characters.
if someString[i] === someString[i - 1] then the characters are repeating, if someString[i] !== someString[i - 1] then they are not repeating, so you return someString[i]
I won't write the whole thing out for you, but hopefully the thought process behind this will help
function FirstNotRepeatedChar(str) {
var arr = str.split('');
var result = '';
var ctr = 0;
for (var x = 0; x < arr.length; x++) {
ctr = 0;
for (var y = 0; y < arr.length; y++) {
if (arr[x] === arr[y]) {
ctr+= 1;
}
}
if (ctr < 2) {
result = arr[x];
break;
}
}
return result;
}
console.log(FirstNotRepeatedChar('asif shaik'));
Here's an O(n) solution with 2 ES6 Sets, one tracking all characters that have appeared and one tracking only chars that have appeared once. This solution takes advantage of the insertion order preserved by Set.
const firstNonRepeating = str => {
const set = new Set();
const finalSet = new Set();
str.split('').forEach(char => {
if (set.has(char)) finalSet.delete(char);
else {
set.add(char);
finalSet.add(char);
}
})
const iter = finalSet.values();
return iter.next().value;
}
let arr = [10, 5, 3, 4, 3, 5, 6];
outer:for(let i=0;i<arr.length;i++){
for(let j=0;j<arr.length;j++){
if(arr[i]===arr[j+1]){
console.log(arr[i]);
break outer;
}
}
}
//or else you may try this way...
function firstDuplicate(arr) {
let findFirst = new Set()
for (element of arr)
if (findFirst.has(element ))
return element
else
findFirst.add(element )
}
function firstUniqChar(str) {
let myMap = new Map();
for(let i = 0; i < str.length; i++) {
let char = str.charAt(i);
if(!myMap.has(char)) {
myMap.set(char, 0);
}
myMap.set(char, myMap.get(char) + 1 );
}
for(let [key, value] of myMap) {
if(value === 1) {
return key;
}
}
return null;
}
let result = firstUniqChar("caabbdccee");
console.log(result);
You can use Map Object and set key and value, where in value you store the count for that particular character, After that you can iterate over map and check where is value 1 and return that key.
Map Object remembers the original insertion order of the keys.
This solution should works with array with integers and string.
function firstNoneRepeating(list, map = new Map()) {
for (let item of list) {
if (map.has(item)) {
map.set(item, map.get(item) + 1);
} else {
map.set(item, 1);
}
}
for (let [key, value] of map.entries()) {
if (value === 1) {
return key;
}
}
}
console.log(firstNoneRepeating("aabcbd"));
console.log(firstNoneRepeating([5, 2, 3, 4, 2, 6, 7, 1, 2, 3]));
let str='aabcbd'
let ans=''
for (let i=0;i<str.length;i++){
if(str.indexOf(str.charAt(i))===str.lastIndexOf(str.charAt(i))){
ans+=str.charAt(i)
break
}
}
console.log(ans)
Fill an empty array with zeros, with same length as the string array, and tally up how many times they appear through the loop. Grab the first one in the tallied array with a value of 1.
function firstNotRepeatingCharacter(s) {
const array = s.split("");
let scores = new Array(array.length).fill(0);
for (let char of array) {
scores[array.indexOf(char)]++;
}
const singleChar = array[scores.indexOf(1)];
return singleChar ? singleChar : "_"
}
You can iterate through each character to find() the first letter that returns a single match(). This will result in the first non-repeated character in the given string:
const first_nonrepeated_character = string => [...string].find(e => string.match(new RegExp(e, 'g')).length === 1);
const string = 'aabcbd';
console.log(first_nonrepeated_character(string)); // c
Here is my solution which have time complexity of o(n)
function getfirstNonRepeatingCharacterInAString(params) {
let count = {};
for (let i = 0; i < params.length; i++) {
let count1 = 0;
if (!count[params.charAt(i)]) {
count[params.charAt(i)] = count1 + 1;
}
else {
count[params.charAt(i)] = count[params.charAt(i)] + 1;
}
}
for (let key in count) {
if (count[key] === 1) {
return key;
}
}
return null;
}
console.log(getfirstNonRepeatingCharacterInAString("GeeksfoGeeks"));
Here is my solution using forEach and convert the string into an array
function firstNotRepeatingCharacter(s) {
var strArr = s.split("");
var found = "_";
strArr.forEach(function(item, index) {
if (strArr.indexOf(item) == index && strArr.indexOf(item, index + 1) == -1) {
if (found === "_") {
found = item;
}
}
})
return found;
}
firstNotRepeatingCharacter("abacabad")
Here is another approach:
Everytime you find equal chars store it in an array and break out of the loop. If the char is not found in the array then you have your first nonRepeating char
function nonRepeatingChars(value) {
const memory = []
for (let i = 0; i < value.length; i++) {
for (let j = i + 1; j < value.length; j++) {
if (value[i] === value[j]) {
memory.push(value[j])
break;
}
}
if (!memory.some(x => x === value[i])) {
return value[i];
}
}
return "all chars have duplicates";
}
console.log('First non repeating char is:',nonRepeatingChars("esen"))
console.log('First non repeating char is:',nonRepeatingChars("esesn"))
console.log('First non repeating char is:',nonRepeatingChars("eseulsn"))
console.log('First non repeating char is:',nonRepeatingChars("esesnn"))
> var firstNonRepeatedCharacter = function (str){
> for(i=0;i<str.length;i++){
> if(str.indexOf(str.charAt(i)) === str.lastIndexOf(str.charAt(i))){
> console.log(str.charAt(i));
> break;
> } } }
>
> firstNonRepeatedCharacter ("areerak");
you can check below link
https://codepen.io/t3veni/pen/wvvxJzm
Easy way to solve this algorithm, very straight forward.
function firstNonRepeatChar(str){
let map = {};
for(let i=0; i<str.length; i++){
if(Object.keys(map).includes(str[i])){
map[str[i]]++
}
else{
map[str[i]] = 1;
}
}
for(let j=0; j< Object.values(map).length; j++){
if(Object.values(map)[j] == 1){
console.log(Object.keys(map)[j]);
return
}
if (j == Object.values(map).length-1 && Object.values(map)[j] != 1){
console.log('_');
return;
}
else{
continue;
}
}
}
nonRepeat("aaabbcccdeeef");
Here is one other solution just using array, using 26 unique character as length of array:
var firstUniqChar = (function(s) {
var arr = [];
var str = s.toLowerCase();
for(let c of str){
let index = c.charCodeAt(0) - "a".charCodeAt(0);
arr[index]? ++arr[index]: arr[index]=1;
}
for(let c of str){
let index = c.charCodeAt(0) - 97;
if(arr[index] == 1){
return c;
};
}
return -1;
}("aabcbd"));
console.log(firstUniqChar);
We can keep track of frequency of each character of the string in an object.
For example : for "aabcbd" we can store the frequency as
{ "a":2, "b":2, "c":1, "d":1 }
This will take O(n) time.
Then we can traverse over this object and find the first character with frequency 1, which will also take O(n) time. So, the time complexity for this approach will be O(n).
const firstNonRepeating=(str)=>{
const obj={};
str.split("").forEach(item=>{
obj[item]
? obj[item]++
: obj[item]=1;
});
const item = Object.keys(obj).find(key=> obj[key] === 1);
return item;
}
Note: I use ES6 Object.keys method which may not work in older
browsers.
//To find first non repeating letter
//It will check for both upper and lower case
//only use one String.indexOf()
var mystr="ohvhvtccggt";
var checkFirstNonRepeating=function(){
var ele=[];
for(var i=0;i<mystr.length;i++) {
var key=mystr.charAt(i);
if(!ele[key])
ele[key]=0;
ele[key]++;
//Just check for second occurance of character
//no need to use indexOf twice
if(mystr.indexOf(key,i+1)==-1 && ele[key]<2)
return mystr[i];
}
return "All repeating letters";
}
console.log(checkFirstNonRepeating());
/*
Input : "ohvhvtoccggt"
Output : All repeating letters
Input :"oohjtht"
Output :j
*/
I used object to keep track of characters count in a string then return the char that has the fa value of 1. Here is a demo:
function firstNotRepeatingCharacter(s) {
// initialize an empty object to store chars
let seen = {};
let letter = '';
// iterate over each char in a string
// if it is already there increase value by one
// else set the value to 1
for(let char of s){
if (seen[char]){
seen[char] +=1;
} else {
seen[char] = 1;
}
}
// iterate over the new constructed object
// if the value is 1 and the output variable is empty
// return the associated key to the value 1
// else return '_'
for(let v in seen){
while(seen[v] == 1 && letter === ''){
letter += v;
return letter;
}
}
return('_');
}
console.log(firstNotRepeatingCharacter("abacabad"));
console.log(firstNotRepeatingCharacter("cbc"));
console.log(firstNotRepeatingCharacter("bcccccccccccccyb"));
console.log(firstNotRepeatingCharacter("aaa"));
The most satisfactory and easy to understand answer is the following.
function firstNotRepeatingCharacter(s) {
const arr = s.split("");
for(let i = 0; i < arr.length; i++){
let chr = arr[i];
if( arr.indexOf(arr[i]) == arr.lastIndexOf(arr[i])){
return arr[i]
}
}
return "_"
}
Explanation: It loops through all the characters of a string from forward and backward and then compares the values. If the index of both forward and backward search is true then it returns that character.
let str = 'aabbcdd';
let val = str.split('').reduce((a, e)=>{ if(str.indexOf(e) == str.lastIndexOf(e)) {a = e }; return a})
console.log(val); // c
the implementation below has a good time complexity and it accounts for letters with different cases:
steps
must touch every character in the string to know if it's repeated or not
function firstNonRepeatingLetter(wordd) {
const chars = {}
let word = wordd.toLowerCase()
// go through chars
// store chars in hash with values of array storing index of char and true if only 1 encountered so far
for (let i = 0; i < word.length; i += 1) {
let char = word[i]
if (chars[char]) {
chars[char][0] = false
} else {
chars[char] = [true, i]
}
}
let output = ''
let index;
for (let key in chars) {
// return char with true and lowest index
if (chars[key][0]) {
index = index === undefined ? chars[key][1] : index
if (index >= chars[key][1]) {
output = key
}
}
}
return index === undefined ? '' : wordd[index]
}
console.log(firstNonRepeatingLetter('sTreSS')) //T```
The bellow solution is a kind of frequency counter pattern and it will run only one loop, so O(n) will be the time complexity.
function firstNotRepeatingCharacter(str) {
const obj = {};
for (let i = 0, L = str.length; i < L; i++) {
const char = str[i];
obj[char] = obj[char] ? obj[char] + 1 : 1;
}
for (let key of Object.keys(obj)) {
if (obj[key] == 1) {
return key;
}
}
return -1;
}
Here is another solution
function firstNotRepeatingCharacter(s) {
const obj = {};
for (let i of s) {
if(!obj[i]) {
obj[i] = 1;
} else if (obj[i]) {
obj[i] = +obj[i] + 1;
}
}
for (let [key, value] of Object.entries(obj)) {
if(value == 1) return key;
}
return "_"
}
Using below method can achieve first non repeated character
function main(str) {
str = String(str).toLowerCase();
let non_repeated_char = 'N/A';
for (let i = 0; i < str.length; i++) {
let currentChar = str[i];
let repeated_times = String(str).split('').filter(e => e == currentChar).length;
if (repeated_times === 1) {
non_repeated_char = currentChar;
break;
}
}
return non_repeated_char;
};
let Result = main("basketball");
console.log("The Non Repeated char is-->", Result);