Amazon Coding Interview Question - firstNonRepeatingCharacter

Поділитися
Вставка
  • Опубліковано 16 січ 2025

КОМЕНТАРІ • 1 тис.

  • @EchoVids2u
    @EchoVids2u 4 роки тому +612

    I once had an interview with this company called ViaSat. I literally only studied 1 coding question the night before and it was this one. Out of pure coincidence, the whiteboard question they asked me to do was this one (the only question I had studied.)

  • @kumaransg1828
    @kumaransg1828 5 років тому +612

    Your channel helped me a lot to brush problem by watching them over and over, finally got a offer from Amazon thanks a lot

  • @dragosgeorge1086
    @dragosgeorge1086 4 роки тому +113

    The complexity of the last solution (with the builtin indexOf methods) is O(n^2). Those methods traverse the array to find those indexes.

    • @Alistair
      @Alistair 3 роки тому +12

      yeah exactly, doesn't seem like a good solution. I would use some kind of structure to keep track of the first encountered position of each character as well as the total count, and you can use that after parsing the string to quickly find the first one, that's O(n)

    • @igornoga5362
      @igornoga5362 3 роки тому +10

      @@Alistair You can also loop over the alphabet instead of whole string, with complexity 26N = O(n).

    • @popularmisconception1
      @popularmisconception1 3 роки тому +1

      the complexity of the solution as presented in code is really O(n^2) but the idea can be coded in O(26*n) (i.e. O(n)) if the outer for loops through the set of 26 possible symbols rather than through the input and records the minimum symbol-indexOf pair. Actually it is a nice representation of the solution with functional/logical programming properties, a version of looking for minimum element.
      Of course the problem can be solved in a single pass, so if really striving for time efficiency, even two passes are two much, more so 26.

    • @billmy2251
      @billmy2251 3 роки тому

      @@popularmisconception1 you mean to take a pair of last and first index for each letter?

  • @dawgsout4free
    @dawgsout4free 5 років тому +258

    Instructions not clear I got hired as the CEO

  • @NathanBLawrence
    @NathanBLawrence 3 роки тому +5

    Another way to think of using an array indexed by each letter’s place in the alphabet is that this is still a hash map. You are deriving the location in memory of each piece of data by using a key’s hash - it’s just that you have a closed set of keys, so you can have an incredibly simple hashing function.

  • @SocajowaRS
    @SocajowaRS 5 років тому +20

    Love the quality of this vid, a chop above your standard stuff nick thanks for putting in the effort!

  • @dmitarzvonimirmitev6644
    @dmitarzvonimirmitev6644 5 років тому +19

    What about LinkedHashMap? They are sorted the way in which you are entering the key-value pair, so we can go with a for-loop in the end just to find the first key that has value 1.

    • @mammlouk
      @mammlouk 5 років тому +6

      I came here to see if anyone mentioned this. If you're going to use a HashMap anyway then you might as well use a LinkedHashMap and then iterate through that to find the first with a count of 1.

    • @dmitarzvonimirmitev6644
      @dmitarzvonimirmitev6644 5 років тому +4

      @@mammlouk Yeah exactly, in general it's better to just use LinkedHashMap over HashMap, just because in the end you know where each element is. And this example here is just perfect for LinkedHasMap.

    • @drmangrum
      @drmangrum 5 років тому +2

      That's the solution I came up with. I used a LinkedHashMap to keep track of entries and a boolean array to mark bad characters. When coupled with streams, you can filter as you're going through the character array and remove items from the map. Then at the end it's just testing if the map is empty or picking off the first key.

    • @nixalot9065
      @nixalot9065 4 роки тому +3

      THANK YOU!! I was yelling this at the screen.

    • @VishalPatel_imvishal
      @VishalPatel_imvishal 4 роки тому

      How would you explain linkedHashMap to the non Java interviewer?

  • @williamragstad
    @williamragstad 3 роки тому +1

    There is one problem with your solutions. For the 26 long array solution, what happens if you give it the input “fall”? ‘a’ will be 1 and ‘f’ to 1, looping through afterwards gives us ‘a’ as the first non repeating character, but what we actually wanted was ‘f’.
    For the first hash-map solution, there are some different implementations which can also affect the order of the keys, which in turn makes the looping through to get the one with count 1 unpredictable and may yield false results.

  • @shahbazalam4565
    @shahbazalam4565 5 років тому +135

    Great video bro... Just a doubt isn't the last solution O(n^2) because maybe .indexOf() and .lastIndexOf() has O(n) complexity internally and we are iterating through the array therefore O(n^2) ???

    • @oblivion_2852
      @oblivion_2852 5 років тому +25

      That's what I thought. I'm very wary of using builtin commands because often times they have their own complexities

    • @JohnTrustworthy
      @JohnTrustworthy 5 років тому +4

      Depends on implementation but in most of the cases yes.

    • @quyenv.nguyen6130
      @quyenv.nguyen6130 5 років тому +4

      @@JohnTrustworthy You cannot perform better than O(n)

    • @JohnTrustworthy
      @JohnTrustworthy 5 років тому +2

      @@quyenv.nguyen6130 Hash algorithms?

    • @Suchoshak
      @Suchoshak 5 років тому +4

      John Trustworthy those would require hash map, not array. And then there wouldn't firstOf make any sense. The best you can do is O(n).

  • @TheTraveler221
    @TheTraveler221 4 роки тому +6

    The indexOf and lastIndexOf implementation, the cost is N^2, because the implementation of this function it's a loop so it will be a loop inside a loop -> n^2

    • @micky2be
      @micky2be 3 роки тому

      Really depends on the language. Since the array doesn't change after the first lookup it will act as a dictionary and spit out indexes without going through the array.

  • @dudaseifert
    @dudaseifert 3 роки тому +13

    Even though time complexity doesn't change, you can still lower the constant by storing the position of the first encounter of the letter, it would change from O(2n) to O(n+26) which on large strings is faster

    • @gblargg
      @gblargg 3 роки тому +2

      The array could store 0 for not encountered, index (starting at 1) if encountered once, and then -1 if encountered more than once. Then just scan the array for the lowest value and remember that index. The only states that need to be remembered are not seen, seen once, or seen more than once. Only seen once needs the index. Thus the other two states can be single integer values different from a valid index.

    • @dudaseifert
      @dudaseifert 3 роки тому

      @@gblargg that would save on memory, but not on speed. adding 26*sizeof(int) to a solution is no big deal, but i guess you're right

    • @starskiiguy1489
      @starskiiguy1489 3 роки тому

      @@gblargg When storing only ~104B+len(sequence)B in memory it's extremely unlikely storage is a larger concern than speed.

    • @gblargg
      @gblargg 3 роки тому

      @@starskiiguy1489 My point was about representation, and thinking about when the location is even required. There is some practical value to not having multiple structures you have to manage separately, and having less redundant state. I think it's useful to be able to explore various ways of implementing things, looking at each from multiple angles.

  • @chon-850
    @chon-850 3 роки тому +1

    i would use a linked list, an array of 26, and a counter for duplicated letters.
    every time the count for a letter changes from 0 to 1, push the letter onto the end of the linked list, change the array[char] from 0 to 1.
    Every time the count for a letter changes from 1 to 2, scan the linked list for the letter and remove it, change the array[char] from 1 to 2. and increment the counter.
    Do not do anything for any count changes.
    if the counter reaches 26 before the end of the input string, return "_" immediately. otherwise, return the first element of the linked list when you reach the end of the string.
    The time complexity is O(n) for scanning input string, plus O(1) for pushing to linked list, plus O(1) for scanning linked list for removal because maximum is 26, plus O(1) for array access.
    Time complexity is O(n + c) = O(n)where c < n for n > 26.
    whereas if you do the hash table and scan you will have O(2n) = O(n), because the unique letter might be at the end so you will have to scan the entire string twice

  • @siddhantjain2402
    @siddhantjain2402 5 років тому +4

    Since we are looking for the first character instance only, we can use a regular variable to store that character. It reduces the memory used.

    • @fidelischarles4545
      @fidelischarles4545 5 років тому +1

      I agree, this way you only really do 1 loop around the string. Another way is to use split and count the length of the resulting arrays hence if the length is 2 then you have your unique character.

    • @LenaYoutube
      @LenaYoutube 5 років тому +1

      @@fidelischarles4545 But the creator of this video kept counting after 2. If the string is long or contains a lot of the same character, we waste some time. Skipping a character would be rewarding. Is there an actual reason to do so?

    • @siddhantjain2402
      @siddhantjain2402 5 років тому

      @@LenaUA-cam Well, to skip the character you first have to check if it's already marked. In a complex data structure, just to find one number can take a whole algorithm.
      At the best it is going to be O(1) time which is the same if not skipping it. In case we were finding all the unique numbers I guess a splitting array makes sense.

    • @fidelischarles4545
      @fidelischarles4545 5 років тому

      @@siddhantjain2402 well said

    • @waisrainy
      @waisrainy 5 років тому

      How does that handle abbbbcddddddeeeeeefffa ? I would use a 2nd map (array or hash) to keep track of position of characters with a count of 1 (remove when it exceeds). At end loop through that 2nd map which is O of the cardinality of the char set (which is constant)

  • @audigex
    @audigex 4 роки тому +3

    A simple optimisation for the double for loop: initiate j as i+1, since there’s no point repeating earlier characters that have already been tested and are known to be repeating

    • @Kiramekushoujo
      @Kiramekushoujo 4 роки тому +3

      This is kinda late but if the string was "aaabcccda" the last 'a' would appear to be non repeating even though it does repeat.

    • @Grassmpl
      @Grassmpl 3 роки тому

      With "aaab" that would return 'a' since the last a would be counted as nonrepeating.

  • @arky5674
    @arky5674 5 років тому +28

    from the thumbnail i thought this was a trick question as they asked you which character is the first non repeating character and the first a is because there were no a's before that a

    • @satibel
      @satibel 4 роки тому

      even if the question was first non sequentially repeating, the first a is repeating since the next character is also an a.

  • @edge30
    @edge30 4 роки тому +1

    you can have an ordinal value starting at 1. instead of storing the count in the hash, you store the ordinal the first time (and increase the ordinal by one), if there was an ordinal already, set it to -1. Then after you finish the array once, you just search the hash for the item with the minimum positive value. That's your 1st non repeated. Instead of O(2n) you have O(n+26) = O(n) which is better specially for big arrays.

  • @ReflectingMe2024
    @ReflectingMe2024 3 роки тому +3

    When I first attempted this I differentiated grammatically between the meanings of 'repeating' and 'repeated'. 'Repeating' I inferred as coming up next to again and again etc i.e. n instances of the same character adjacent to each other, whereas 'repeated' was what I inferred that the question is actually asking for i.e. is repeated elsewhere in the string. Semantics maybe, but don't get caught out folks like I did :)

    • @huckleberryginesta7941
      @huckleberryginesta7941 2 роки тому

      why its always important to ask clarifying questions to an interviewer if you're not sure.

  • @foodice11
    @foodice11 5 років тому +2

    You could also start at the back and keep a list of all chatacters found. Then every time you find a character you haven't yet seen, you store that as your candidate. The last one standing is the one.
    Edit:
    I suppose that you would have to search the string as much as you search the hash table. If not one time less since you don't have to do it at the end.

    • @satibel
      @satibel 4 роки тому

      it would be ~O(26n) instead of ~O(2N) since you go through a 26 char array N times. it would actually be faster to dummily increment each value in some sort of ordered hashmap and search after for count==1.

    • @joshcaithness8123
      @joshcaithness8123 3 роки тому +1

      @@satibel For example dictionaries in Python

  • @The5thUSER
    @The5thUSER 4 роки тому +18

    Here’s my solution, i believe it only takes a single for loop (O(n)):
    - Start at the end of the string, iterate backward
    - Keep a hash map as in the video with the number of occurrences
    - Also keep a single character which represents the last encountered letter
    - In the loop:
    1. If the character has been seen already (hash map not zero) add 1 and continue
    2. Of the character has NOT been seen already (hash map is zero) add 1, update the “last seen” character, and continue
    - This way, we skip all the repeated characters once they are logged
    - Once we get to the end of the loop, if the count of the “last seen” character is 1, then return that character (I.e. it was unique and closest to the start) otherwise return underscore
    Amazon pls hire me for all your weird string filtering needs

    • @slathian1223
      @slathian1223 4 роки тому

      That is the correct answer, although it wouldn't matter if you went forwards or backwards. You could also hash more information about the different locations, number of iterations when to break. and so on.

    • @jajefan123456789
      @jajefan123456789 4 роки тому +3

      This is an incorrect solution. It would fail, for example, on case “aaabbaac”, returning b instead of c. The best case scenario is O(2n) no matter what, and I’m too tired to write out why right now. Ping me later to hear an explanation.

    • @anujramaswamy6809
      @anujramaswamy6809 4 роки тому +1

      @@jajefan123456789 too long i didnt read his solution fully. But I feel this was his idea. It will return c because it was the last character with count = 1
      pseudocode
      dic = {}
      lastCharWithCountOfOne = " "
      for(end, beginning):
      dic[character] += 1
      if dic[character] == 1:
      lastCharWithCountOfOne = character
      if lastCharWithCountOfOne != " " :
      return lastCharWithCountOfOne
      else:
      return "_"

    • @VishalPatel_imvishal
      @VishalPatel_imvishal 4 роки тому +1

      @@anujramaswamy6809 would this works? You sure?

    • @FinBoyXD
      @FinBoyXD 3 роки тому +1

      This doesn't work. It cannot keep track of the correct last seen unique character in a single variable.
      Just take the Wendell Wu example: "aaabbaac". At first the variable is c. Then it will instantly change to a, because it is the first occurence of that letter. It doesnt know that there will be more a's. So already we have lost the correct letter, which was c. Then it will update to b, and at the end it wont even return that, because it wasnt unique, it will return underscore, which is wrong.

  • @crud41
    @crud41 5 років тому +2

    You don't actually need a hashmap. Just create a bit vector associated with the character's ascii value. You don't care how many times it happens, just update a single bit. It will be almost constant time/space since you only need 56 bits to represent the entire a-zA-Z alphabet.

    • @VilasNil
      @VilasNil 5 років тому +1

      I thought exactly the same, but the only thing you have solved is which letters of the alphabet have a representation in the string and which of them appear more than once, hence lacking the knowledge of which is the first letter that appears only once.
      To solve this, you can XOR both vectors and loop through the string again, when you access such XOR'd vector and find a 1/True, you found the first non-repeating letter. It is O(2*N) which simplifies into O(N). You can check if the XOR gave 0 before looping to know if there were no letters satisfying the criteria.
      It is worse than other implementations but it is the least memory-hungry one. Only 2 long int to save all that information (plus whatever pointer/index you use to loop).

    • @crud41
      @crud41 5 років тому +1

      @@VilasNil good point.

  • @Krechevskoy
    @Krechevskoy 5 років тому +6

    I find myself tempted to use recursion here:
    // Find the first non-repeating character in a string
    // Returns null for empty strings and strings with no unique chars
    function findFirstNonRepeatingChar(str) {
    // Get the first character of the string
    let char = str.charAt(0)
    if(!char) return null;
    // Replace all instances of that character
    let repl = str.split(char).join('')
    // Recurse if you replaced more than one character
    if(str.length - repl.length > 1) {
    return findFirstNonRepeatingChar(repl)
    } else return char
    }

    • @paulstelian97
      @paulstelian97 5 років тому

      Thankfully the stack depth won't be fucked but can you tell me O(what) this is? (time and memory) You need to have this skill at the interview (I stopped myself from giving you the answer).

    • @Krechevskoy
      @Krechevskoy 5 років тому +1

      @@paulstelian97 That's a good point... The worst case would be all duplicate characters, so I guess it would be O(n * k), where n is the length of the string and k is the number of unique characters (max 26). There are only 26 letters in the question, so it's a maximum stack depth of 26, and the string shrinks by at least 2 until an answer is found...
      That said, you make a good point. Recursion makes the code easier, but it takes way more memory/stack space than a simple loop.

    • @paulstelian97
      @paulstelian97 5 років тому

      @@Krechevskoy Sure. Since k is limited by 26 you may as well replace it by 26 (big-O shows the worst case indeed) which disappears as O(c * n) = O(n). So it is linear time, and I'm not sure what to understand of what you said from the memory point of view (the correct answer is also linear for the same reason)

    • @Krechevskoy
      @Krechevskoy 5 років тому +1

      @@paulstelian97 Yes, the memory is also linear, but it is also worse than a simple loop because of the recursion. Each stack frame needs to hold a (shorter) copy of the string, which is the typical downfall of recursive functions.

    • @paulstelian97
      @paulstelian97 5 років тому

      @@Krechevskoy The best algorithm has constant space (input is not considered if treated as read only).

  • @sabazillo
    @sabazillo 3 роки тому +1

    Another more mathematical solution could be assigning each letter a prime number and using a for loop multiplying each prime number associated to the corresponding character, after that with other loop you start from left to right checking the reminder of dividing that result by the corresponding prime squared (with the operator %) if the answer is different than cero you return that character.
    Sorry for bad English, please ask if you have any doubts.

    • @blazejeczek8710
      @blazejeczek8710 3 роки тому

      Yea, but as far as I understand your solution you would multiply even 100000 times which would cause an integer to flip.

    • @sabazillo
      @sabazillo 3 роки тому

      ​@@blazejeczek8710You only have to multiply once per character, but you are right, that could be a problem with really long character strings.

    • @sabazillo
      @sabazillo 3 роки тому

      @@blazejeczek8710 for example, with the string abbcdda you get 2*3*3*5*7*7*2=8820 which can be divided by 2^2, 3^2, 7^2, the only prime squared in the list that cannot divide that is 25=5^2, so the result should be c.

    • @blazejeczek8710
      @blazejeczek8710 3 роки тому

      @@sabazillo yea that is a clever solution in mathematical sense and it reminds me of a concept called hashing that can be used in other string/text problems (don't know if you are familiar with it):
      Basically you do what you've talked about - choose a prime number for each character and multiply it and you add an additional step which is moduling each time by a choosen number, preferably a big prime like 10^9+7 (you don't ever overflow).
      This way you can easily check whether 2 strings are composed of the same number of the same characters.
      Example: you know that "aabbc" is the same as "abcab" because it has the same hash value.
      But in this problem I think other solutions might be better due to the overflow issue.

  • @CharlesFlahertyB
    @CharlesFlahertyB 4 роки тому +6

    Make one pass through the string and calling split with each char (str.split(substr(i,1))). If the resulting length = 2 then the char is unique.

  • @wyk6318
    @wyk6318 5 років тому +38

    this video is more “phone user” friendly than the previous ones. Love it!

    • @WaveTVsubscribe
      @WaveTVsubscribe 5 років тому

      yikan wang get a computer broke ass

    • @jackytaly
      @jackytaly 4 роки тому +9

      Wave TV I have a very good computer, still prefer mobile most of the time because if I’m on my computer I’m usually playing a game

    • @wyk6318
      @wyk6318 4 роки тому +7

      Jack haters gonna hate. My laptop is above 1k. I brought UA-cam premium to watch this channel. I guess he’s gonna call me poor still. Just ignore him.I rather think he’s pathetic and feel a little sorry for him born in a bad family.I lift five times a week and keep myself lean all the time. If he hustles like we do he doesn’t got time to hate.I’ve reported him.

    • @chiragsingla.
      @chiragsingla. 3 роки тому

      For some reason I code on my phone and not in pc most of time

  • @batmansmk
    @batmansmk 4 роки тому +7

    indexOf is O(n) in all arrays implementation in languages I know. So the last solution, despite being elegant, is O(n^2).

    • @aniruddhashevle
      @aniruddhashevle 3 роки тому +1

      Exactly my point. Hence hash maps/array of alphabets counts could be better than indexOf!

  • @seanvinsick
    @seanvinsick 4 роки тому +3

    The third method using built in functions is dangerous, especially in an interview. It assumes that the built in function isnt bigger than polynomial. Your code code be constant time and the functions could be exponential. Whether it is or isnt, really isnt the problem, but before you opt to use it, be prepared to explain what its doing. Last but not least, a function call creates overhead, and doing a function call on each element will slow you down as the set grows. If you're trying shave off cycles, it's definitely a poor approach to call two function calls.

  • @turn1210
    @turn1210 5 років тому +3

    I like the last one. My solution was to take each letter in sequence, and then compare the string length, to the string length with that letter removed. If the result is 1 then you have the first non repeating letter, if not, use the string that has that letter stripped as the new input, and repeat until you get 1 as the difference in string lengths.

    • @markzamiebarrientos5904
      @markzamiebarrientos5904 5 років тому

      Nice

    • @HeyItsSahilSoni
      @HeyItsSahilSoni 5 років тому

      The last one in video doesn't work for the case there is no single occurance character, it'll print the last instance of any repeating character.
      Your solution works tho

    • @mammlouk
      @mammlouk 5 років тому

      @@HeyItsSahilSoni How does it not work? .indexOf always returns the first index of the item and .lastIndexOf always returns the last index of the item. If they are not equal the function returns "-". It will not return the last instance of a repeating character.

    • @harrywang4769
      @harrywang4769 5 років тому

      So iterate over a string 26 times? You would fail my interview

  • @jenesaispas4506
    @jenesaispas4506 3 роки тому +1

    i'm not sure but i think that there is a way simpler thing to do. convert the string to byte array then a for loop and at each iteration get the character in the array and verify if the character before and after is the same if not it's the first non repeating char

  • @HareendraTejaReddyDonapati
    @HareendraTejaReddyDonapati 3 роки тому +12

    Have a Hash-map/Dictionary for “first occurrence” and the “occurrence count”
    For each char in string when you add for firs time to “occurrence count” add the index to “first occurrence” and then pick the first based on values of both hash-maps.
    Store the value for each char in string as a object which has first occurrence index and no of occurrence
    Filter by no of occurrence and check the lowest first occurrence

    • @RhymesWithCarbon
      @RhymesWithCarbon 2 роки тому

      This is how I approached it at first. I’d have a list of occurring characters and a list of first indices. When I find a second occurrence, I eliminate it from the list of first indices (and don’t write it there again). When the string is complete you’ve got your answer in the first slot of the first (non-null/missing) indices array.

  • @MaharshiYadav
    @MaharshiYadav 3 роки тому +2

    You can also optimize complexity by using map pair(0) will contain the frequency and pair(1) will contain the index of the char.
    So looping through map for finding solution will not always be O(n)

    • @yissssss
      @yissssss 2 роки тому

      You could also just remove the char from the original string as you loop through if it if it is repeated by looking at the map. Then at the end the first char is either the first non repeated char or the string is empty.

  • @TheDRAGONFLITE
    @TheDRAGONFLITE 3 роки тому +4

    What if you loop through once - using a dict with the key as the letter and the value being the index. Then you return the character with the lowest index out of all non repeating chars at the end...

  • @Mekelaina
    @Mekelaina 4 роки тому +1

    my first thought, was create an array size 26 (one for each possible character) and when you check each character in the string, increment the element for said character by 1. (so each time youd encounter 'a' then arr[0] += 1, for each character in string) then once done, loop through the array and find the first element == 1 and return that. if all elements are != 1 then you know that there are no non repeating characters. and would thus return '_'. id probably also create a constant string with all possible characters in order to simplify the conversion between tracking array and corresponding character.
    not the most efficient way, but its simple, easy to implement, and does the task. and can be done with 2 loops in said function.

  • @bernardobritto8352
    @bernardobritto8352 4 роки тому +4

    I just started programming and I am really happy that this was the first interview question that I managed to get it done so I am going to post my code here and hope that one day in the future I will come back to this video and see it again.
    string = 'aaaaaaaaccccccccceeedf'
    lista = list(string)
    lista_copy = lista[:]
    first_non_repeated = None
    for element in lista:
    being_analysed = lista_copy.pop(0)
    if being_analysed in lista_copy:
    while being_analysed in lista_copy:
    lista_copy.remove(being_analysed)
    else:
    first_non_repeated = being_analysed
    break
    if first_non_repeated:
    print(first_non_repeated)
    else:
    print('There is no non repeated symbol')

    • @Shuizid
      @Shuizid 4 роки тому

      That's python code, right?
      I tested it an it throws an error when there is no non-repeated character: "pop from empty list"
      Your for loop is in fact broken and needs to be replaced - because it goes through every element in lista, which is: a, a, a, a, a.... -> meaning it will run len(lista) times and causes the pop-error because if you don't reach the break, it will end up with an empty lista_copy while still within the loop because len(lista) is so long.
      I streamlined your code a little, by using a while-loop with an else (the while-else is executed at the end of the while-loop, however the break exits the loop and skips the while-else as well).
      string = 'aaaaaaaaccccccccyceeedydff'
      lista = list(string)
      while len(lista) > 0:
      being_analysed = lista.pop(0)
      if being_analysed in lista:
      while being_analysed in lista:
      lista.remove(being_analysed)
      else:
      print(being_analysed)
      break
      else:
      print('There is no non-repeated symbol')

    • @bernardobritto8352
      @bernardobritto8352 4 роки тому

      @@Shuizid I didnt get this error but I did it again and endend the same way as your code(almost)
      string = 'aabbbced'
      lista = list(string)
      P = False
      index = 0
      while lista:
      element = lista[index]
      if lista.count(element) > 1:
      while element in lista:
      lista.remove(element)
      pass
      elif lista.count(element) == 1:
      print(element)
      P = True
      break
      if not P:
      print('Tehre are no repeated elements')

  • @kouyang1771
    @kouyang1771 3 роки тому

    my initial thinking is use a hashmap and populate it with all letters with 0 as its pair. Everytime we see that char, check if its in hashmap, if it is, then increment the int associated with it by 1 if its 0. If its 1, then that means we found a 2 instances of that char in the string and we remove that key value from the hashmap. We would also keep a stack or queue to keep track of which char was found first. Every time we discover a new char, we push onto the stack/queue. Then whenever we remove a char from the hashmap, we also remove it from queue/stack. The stack/queue only ever keeps one instance of the chars. Its purpose is purely to keep track of when we find a new char in that order. At the end of iterating through all char in the string, we return the First element in the stack/queue. If its empty, return the '_'. This would give time complexity of O(n) as we have a single for loop to iterate the string. A space complexity of O(52) since we only ever keep track of 26 characters in our hashmap and stack/queue at worst (string has all characters once).

  • @ShashiBhushan2k13
    @ShashiBhushan2k13 5 років тому +3

    I actually used a LinkedHashMap with my initial solution so I don't have to loop through String twice, but the raw array version takes less than half the time with longer strings.
    Also while writing test case for this, learned that in Java, String literal could be maximum of 2^16 characters in UTF-8 encoding. thanks for teaching me something new today :)

    • @lovelycode7173
      @lovelycode7173 3 роки тому

      You still have to iterate through the entry set of the map however which shares the length of the string, so this solution would still be O(2n)

    • @cas1652
      @cas1652 3 роки тому

      Entry set is the string anyway so not sure would be worth.

  • @mr.rabbit5642
    @mr.rabbit5642 4 роки тому +1

    My initial thought was to create a hashmap (I guess, haven't gone through DSs yet :x), and as we loop through the String, we either add this letter and it's index to the map (if it hadn't occurred yet), or change the index to -1 (if it did). Then we just return the letter at smallest, but positive index (or '_' if all are negative) and voilá. This way we only have records for letters that occurs. Especially efficient for long-ass Strings of only 8 or so distinctive characters

  • @ragingpahadi
    @ragingpahadi 4 роки тому +20

    LinkedHashMap can keep the order !

  • @LetrixAR
    @LetrixAR 4 роки тому +1

    I was thinking of iterating over the string and save the char in a list, then, if the next character is on the list, delete it. Then, at the end, return the first element of the list.

  • @iippari7
    @iippari7 3 роки тому +3

    I tried this out before watching the video -- here's what I came up with:
    public static char firstNonRepeating(String input) {
    // At the end of the loop, output contains all possible candidates for non-repeating characters
    String output = "";
    /* 26 is more than enough for our puny, English lowercase minds...
    * We keep track of which characters we've seen with a boolean array.
    * In the biz, this is called premature optimisation, and it's bad.
    * */
    boolean[] disallowed = new boolean[26];
    for (char c : input.toCharArray()) {
    /* You can actually do arithmetic with chars
    * Subtracting 'a' from the char just normalises
    * it to a value we can use to index the boolean array
    * */
    if (disallowed[c - 'a']) {
    // There are more efficient ways to replace the now-repeated character, but this works too.
    output = output.replace("" + c, "");
    continue;
    }
    output += c;
    disallowed[c - 'a'] = true;
    }
    return output.isBlank() ? '_' : output.charAt(0);
    }
    It's O(n) in theory but probably closer to O(n^2) in practise because of the replace call. You could make it more efficient by using a linked list of characters and keeping track of the characters' indices -- that'd probably get it down to O(n) even.

  • @DaGamingDragon2
    @DaGamingDragon2 3 роки тому +2

    I create a time complexity of O(n+m) using a LinkedHashMap in Java, where n is the size of the input and m is (at its worst) the 26 letters in the alphabet. For the LinkedHashMap, the key is a char and the value is each time it appears in the string. First loop loops through each letter in the string and charing it, adding new keys each time it finds it or incrementing the existing key's value by 1. After this loop finish, the last loop will iterate thru the LinkedHashMap's keySet and because LHM's are special in that it maintains the order as each key is added. When it reaches the first key with the value of 1 simply return the key. If it loops through all (at its worst 26) possible keys without getting a value of 1, then return the "_".

  • @1gnore_me.
    @1gnore_me. 4 роки тому +3

    youtube has been recommending me a lot of coding videos lately and I love it

  • @micky2be
    @micky2be 3 роки тому +1

    For the second loop you could build an array during the first loop, to save the order of first time seen. Which will be a length of 26, so an O of N+26.

    • @micky2be
      @micky2be 3 роки тому

      Similar idea if using JavaScript would be to use a Map object, instead of a literal one. Then you can iterate through properties, since it does by order of creation.

  • @ZeroSleap
    @ZeroSleap 4 роки тому +76

    The naming is a bit fail,i'd suggest the function be named firstUniqueCharacter

    • @jamoinmoin
      @jamoinmoin 4 роки тому +25

      Exactly my thought. The name suggests "aabaabbb" would return b, but in this solution it wouldn't.

    • @jasperdiongco4668
      @jasperdiongco4668 4 роки тому +1

      Yeah, I agree with this.

    • @e_tas_
      @e_tas_ 4 роки тому

      Except there's already such a thing as a "unique character" such as $, &, #, @, etc. It's supposed to be as clear as possible.

    • @inordirectional
      @inordirectional 3 роки тому +2

      @@e_tas_ Never heard anyone refer to non-alphanumeric characters as 'unique characters' though. Nonrepeating is clearly ambiguous, unique is less so.

    • @e_tas_
      @e_tas_ 3 роки тому

      @@inordirectional "The Unique Characters rule rejects passwords that do not contain a minimum number of unique characters. For example, the password "aaaaaaaa" only contains one unique character (a), whereas "mypassword" contains nine unique characters (mypasword)."

  • @awkwardlycharming
    @awkwardlycharming 4 роки тому +1

    He could use additional memory(also helps with additional character sets, m is at worst the set of the characters) and just use a linked list and add a character on everytime a new character is seen by checking the hashmap for number of occurrences. Then at the end of the first iteration of the array of characters, iterate through the linked list(which should just be the order of characters indvidually), then check for each character in hashmap. First one to have a value of one is it. That should be a complexity of O(n+m) e.g.
    itt 1:
    _
    string: aabddddbc
    Hash: {a:1}
    linked list : (a)->()
    itt 2:
    _
    string: aabddddbc
    Hash {a:2}
    linked list: (a) ->()
    itt 3:
    _
    string: aabddddbc
    Hash {a:2, b:1}
    linked list: (a) ->(b)->()
    ..........
    last itt, itt n:
    _
    string: aabddddbc
    Hash {a:2, b:2,c:1,c:4}
    linked list: (a) ->(b)->(d)->(c)
    Iterate through linked list checking hash for first ct of 1 of the character and stop.
    NOTE: PLEASE LET ME KNOW IF I MESSED UP SOMEWHERE

  • @poojaguru2516
    @poojaguru2516 4 роки тому +17

    Awesome, the way you explain makes programming even more interesting🔥

  • @cibureh2684
    @cibureh2684 4 роки тому

    Instead of an integer array you can also use just one integer. Since an int has 4 bytes, we have 32 bits available. Given that the string only contains English characters we have enough space. Each bit in the int can be flipped "on" (1) and "off" (0) when we encounter a character (e.g., if we see an "a" we mark bit 0 to 1.. if we see an "a" again we mark it back to 0). In the end we scan through the string again and return the first character which has a 0 in the bit representation at the position of the character in the English alphabet.

  • @bakutabata8798
    @bakutabata8798 4 роки тому +4

    You needed to capture the index to find the first non-repeating character. Your answer assumes the string is in alphabetical order.

    • @sfitz219
      @sfitz219 4 роки тому +3

      He didn't capture the index, but he does still have access to the string. That last for() loop is looping over the characters in the original string and checking them against the count in his hashmap until it finds one that appears only once. It's funny though, the first method I tried, I actually did make that mistake and returned the character that appears once in the String which is alphabetically first

  • @alexluz321
    @alexluz321 4 роки тому +1

    Even though the runtime is O(n) after two runs, we can do this in one run over the list and optimize the runtime over memory usage by using a DoubleLinkedList and two Sets.
    Just add the elements to the end of the List if they are not yet in the "seen" Set, remove if already found. Just return the head of the list.

    • @shrikantwankhede8317
      @shrikantwankhede8317 4 роки тому

      what about the time required to traverse the list...i am bit confused...can u explain the time complexities involved in it

    • @alexluz321
      @alexluz321 4 роки тому

      @@shrikantwankhede8317 I don't know if I was clear when I meant "optimize". I didn't mean we would get to O(1) but we could spare one run over the array, essentially still being O(n), but with only one pass over the array. So it's just an optimization, not really so much improvement on the theoretical complexity.

    • @shrikantwankhede8317
      @shrikantwankhede8317 4 роки тому +1

      @@alexluz321 okay....got it , thanks for replying

  • @winnieww
    @winnieww 4 роки тому +12

    How I wish I get these problems during interview. I somehow always get maze, graphs problems :(

  • @ToyMachine22122
    @ToyMachine22122 4 роки тому +2

    Nice video!
    Just a tip, in this instance you don’t need a Dictionary (aka Hashmap) because we don’t care about counting how many times a character occurs; we only care about whether or not it occurs more than once.
    A set (C++) or HashSet (C#) is the data structure you’re looking for. Not sure what it’s called in Java.

    • @VishalPatel_imvishal
      @VishalPatel_imvishal 4 роки тому

      And how do you do that with HashSet? How do you know if the number is repeated or not repeated?

    • @ToyMachine22122
      @ToyMachine22122 4 роки тому

      Vishal Patel initialize an empty set. For each character, check if it’s in the set. If not, add it to the set and continue. If so, then we know that it occurs more than once.

  • @JOELwindows7
    @JOELwindows7 5 років тому +16

    This is your daily dose of Recommendation
    .

  • @curruption018
    @curruption018 4 роки тому +2

    I stumbled upon this video and thought "oh this question is simple" and quickly realized it's a bit more difficult than I expected. took me about 35-40min to get this done w O(n) complexity and O(1) space. Great video

    • @VishalPatel_imvishal
      @VishalPatel_imvishal 4 роки тому

      How did you able to do in O(1) space?

    • @curruption018
      @curruption018 4 роки тому

      @@VishalPatel_imvishal create a hash table with all letters as keys and ints as values. traverse the whole str and increment all the key-values in the table. Then go back through the same string again and search each letter of the string in the hash table. The first letter that comes back with the value of 1 is the first non-repeating thus O(1) space.

  • @tannerbarcelos6880
    @tannerbarcelos6880 5 років тому +8

    I literally thought hashmap initially. But what scared me from that idea was handling if that was the first non repeating character. It isn’t sorted so there isn’t a way to know just off that. And my mind kinda went blank from there

    • @kolliparachandana
      @kolliparachandana 5 років тому +1

      Tanner Barcelos same here

    • @amoghvk5
      @amoghvk5 5 років тому

      you can use linkedhashmap it will sort the keys in added order.

    • @tannerbarcelos6880
      @tannerbarcelos6880 5 років тому

      amogh kulkarni hmm okay. I like that. Does that require extra time though ? If you’re inserting the key/value pair, that sort at best , could be log n maybe? and that’s extra time on top of simply inserting in a normal hashmap in 0(1) .
      I personally like the idea of 1 pass to put in the map and then pass once more over the string and comparing that to the value at that key and if it’s the first value that’s 1, return that key. But I wanna look into your solution. I didn’t know it was a thing

    • @amoghvk5
      @amoghvk5 5 років тому

      @@tannerbarcelos6880 Here is what i did. Now, i dodnt know how much time it will take, you can calculate and share the findings here.
      String sample = "ababcd";
      Map sampleMap = new LinkedHashMap();
      for (int i = 0; i < sample.length(); i++) {
      char c = sample.charAt(i);
      if (!sampleMap.containsKey(c)) {
      sampleMap.put(c, 1);
      } else {
      sampleMap.put(c, sampleMap.get(c) + 1);
      }
      }
      System.out.println(sampleMap);
      for (Entry entry : sampleMap.entrySet()) {
      if (entry.getValue() == 1) {
      System.out.println(entry);
      break;
      }
      }

  • @justabhishek
    @justabhishek 3 роки тому

    Hash map does not maintain order. So in this case when looping through the map, it’s not guaranteed that you get the first character that has 1 as the value.

  • @bjorno43
    @bjorno43 4 роки тому +3

    First solution that came to my mind was to split the string on each character into an array. Then delete duplicates from it and return the first index or underscore if the array is empty. Not saying it's the best solution, just the first thing I thought of.

    • @makagyngrimm3392
      @makagyngrimm3392 3 роки тому

      Wow this is indeed O(N) time complexity. Though the constant that is multuplied by N here is way larger than the optimal solution.

    • @Daniel_WR_Hart
      @Daniel_WR_Hart 3 роки тому

      @@makagyngrimm3392 Wouldn't deleting all duplicates be O(N^2) though? For every letter you'd have to scan the rest of array for the same letter to delete.

    • @makagyngrimm3392
      @makagyngrimm3392 3 роки тому +1

      @@Daniel_WR_Hart no you dont scan. you loop through the array again

  • @cipherxen2
    @cipherxen2 4 роки тому +1

    Use 2 arrays of length 26. One for occurance count and other for first occurrence position. After populating these arrays just find the char with occurrence count 1 and minimum first occurrence. It'll give O(n+26) which will better then O(2n). I know both are equivalent to O(n) but for large n, it'll make much difference.
    I consider O(2n) = O(n)+O(n) and O(n+26) = O(n) + O(1)

  • @campermortey
    @campermortey 5 років тому +17

    I love your videos man. So helpful. Another solution that’s better than brute force but isn’t as good as the optimal is to sort characters O(nlogn) and compare the characters next to each other

    • @JohnTrustworthy
      @JohnTrustworthy 5 років тому +18

      Won't that alter the first occurrence? Say you have "bccca". When you sort you'll have "abccc".

    • @JohnTrustworthy
      @JohnTrustworthy 5 років тому

      @Harsh Mehta That could work if the mapping was ( old index : new index ). Then you iterate using the new indexes by retrieving them from the mapping by calling the old indexes from 0 to n. Then all you'd have to do is compare both adjacent elements.
      for(int oldIndex=0;oldIndex

  • @dankhnw8
    @dankhnw8 5 років тому +1

    I thought of something else. For each letter put you find it has a duplicate put it in an array and precheck each character if it exists in the array then proceed on. If all goes well it will return the requested character. But ik your way is way more effective since arrays take a lot of space in memory and the process will be slower cuz you'll have to precheck everything with an extra for loop. I need to be more comfortable with using boolean lol

    • @paulstelian97
      @paulstelian97 5 років тому

      I have combined his way and your way actually. Have an array of 26 counters (made them int8_t or char because you only need to distinguish between 0, 1 and >1, you don't need specific count when in >1 case) and a string of capacity 27 which is appended the first instances of each character I encounter (capacity 27 so I also have a NUL terminator).
      After the string is done I loop through the second array and use the first one to stop at the first character which has a count of 1 rather than >1. Then if this loop finishes I will return the '_'.

  • @sercancelenk7131
    @sercancelenk7131 3 роки тому +4

    Question from a beginner: what if the string were to be not listed in alphabetical order, and mixed?

    • @jlacr8056
      @jlacr8056 3 роки тому +1

      that wouldn’t matter at all, if we are searching through the entire list and mapping it the order does not change anything

  • @coreynorlander5596
    @coreynorlander5596 3 роки тому

    I think a better solution is instead of storing the count store the index you found the character at initialized as -1. When you see a character update the -1 to the index or if it's already not -1 remove it from the hash map. At the end just loop through the hash map looking for the lowest value that isn't -1. This is much closer to actual O(n) for along strings as the second loop you only need check max 26 keys. If you want to get even more efficient you can still do your method when the number of keys is greater than the length of the string.

  • @MsJavaWolf
    @MsJavaWolf 5 років тому +4

    I understood the question differently. I would think a non repeating character is not the same as a character that only occurs once.
    For example in abbac I would say a is the first non repeating character, even though there are 2 a, I mean it doesn't repeat, there is a b after the a.
    Most recruiters appreciate it if you ask questions to clarify the task.

  • @anonymousvine4105
    @anonymousvine4105 3 роки тому

    It’s worth mentioning (but not coding) the O(nlog(n)) solution too. If we sort the array, then repeating characters are next to each other. Then we can use two adjacent looping pointers, curr: one that stores the current character it sees, next: for the character at i + 1, and a third variable for running tally. If the next character identified by the pointer is a different character and the tally == 1, return arr[curr]. If we reach the end of our array with the next pointer and it’s equal to arr[curr], return our “_”. This is constant space and is a legitimate tradeoff vs a constant time, linear space solution, though we usually prefer faster time over lower space. Writing the sort function for characters can be annoying too, taking up about 10 minutes. On a real interview, you want to mention all of this, then get to writing the code for the solution that you can reasonably implement in 30 minutes.

  • @AnkitKumar-ow6fg
    @AnkitKumar-ow6fg 5 років тому +7

    Bro, i have seen many videos for competitive programming and none of them explained the solutions or even the questions this way. Keep up the good work. Your videos really helped me a lot. 😊

  • @AlejandroAnzolaAvila
    @AlejandroAnzolaAvila 3 роки тому +1

    A better solution could be O(n + 26) = O(n) [lower than your O(2n) = O(n)], by just having the same 26 size array indexed by the number of the letter as you explained, but instead of storing the count you could store the index where you first found the letter, if during the traverse you find that there is a repetition then set the index as -1. After finishing the traverse, just check the 26 size array and find the lowest index in there, if all of them are -1 then there the answer is "_"

  • @babumon5351
    @babumon5351 5 років тому +3

    HashMap is a wrong choice. Hash map doesn't guarantee the order of insertion. You need to use LinkedHashMap if you want to preserve the insertion order in java.So in your example at 8:50 , it may give you d or f, if you are using normal HashMap.

    • @NickWhite
      @NickWhite  5 років тому +1

      hashmap is fine here

    • @NickWhite
      @NickWhite  5 років тому +9

      we’re not looping through the hashmap which i explain in the video we’re looping through the string once again and doing lookups to fine the first character that has a frequency of 1

    • @nishthavan3764
      @nishthavan3764 5 років тому +1

      hashmap will do just fine

    • @nitchow
      @nitchow 5 років тому +1

      Shery's right - HashMap doesn't guarantee the order of insertion (www.geeksforgeeks.org/differences-treemap-hashmap-linkedhashmap-java/). The Python OrderedDict guarantees the order of insertion (docs.python.org/3/library/collections.html). Here is basically the above implementation using OrderedDict -
      import collections
      from collections import OrderedDict
      def firstNonRepChar(inpStr):
      odS = OrderedDict()
      for c1 in inpStr:
      odS[c1] = odS.get(c1, 0) + 1
      for c1 in odS.keys():
      if odS[c1] == 1:
      return c1
      return '_'

  • @TerjeMathisen
    @TerjeMathisen 3 роки тому +2

    This one is obviously doable as O(n): Two 26-element arrays, one (count) initialized to 0, the other (first_seen) to MAX_INT, then loop through the input, starting at the back end!
    do {
    c = inp[--pos] - 'a';
    count[c]++;
    first_seen[c] = pos;
    } while (pos);
    Afterwards we just do the constant-time scan of those two arrays looking for those with count==1 and first_seen as low as possible.
    For extra credit write a SIMD version (somewhat hard to make efficient). A GPGPU would actually be more straight-forward. With really large inputs we could do a multi-threaded version with a reduction step/merge of the partial results at the end, this should easily be able to saturate the memory bus.

  • @debajyotiroy6843
    @debajyotiroy6843 4 роки тому +3

    Nick white is by far the most legit channel for preparing for coding interviews...thanks dude for making this channel a full fledged community...

  • @hritwiksom3032
    @hritwiksom3032 4 роки тому

    Fact: The HashMap solution is considered O(n) space as number of inputs isn't fixed, while the frequency array[26] approach is O(1) space as range of input is predefined, what's funny is the HashMap might actually use less space than the frequency array, as the frequency array also has to allocate space for non occurring characters.

  • @adityagoswami6881
    @adityagoswami6881 5 років тому +6

    The most simple and straight forward explanation you could find for this question,
    Can you provide the code for all 4 approaches using C.

  • @ExplorerForLifetime
    @ExplorerForLifetime 3 роки тому

    Second method of using 26 array elements will not work for input like “azavbb” (seen in this video at 1:00), as it will have 1 for both ‘z’ and ‘v’, when we scan array to check for first element with 1, we get ‘v’ but correct answer in that case is ‘z’ as it is the first non repeated letter when scanning from left to right.

  • @aleksd286
    @aleksd286 5 років тому +11

    What's stopping you from creating a second hash map with key value pairs of first indexes, meaning a: 0, b: 1, c: 2 etc

    • @brianotienotruimp
      @brianotienotruimp 5 років тому +1

      Hi Aleks, you are likely to have a key more than once which violates the building components of hashmaps and won 't be efficient for what you are looking for

    • @aleksd286
      @aleksd286 5 років тому

      @@brianotienotruimp how can a hashmap/dictionary key get violated?

    • @brianotienotruimp
      @brianotienotruimp 5 років тому

      Aleks D you can’t have the same key twice

    • @tobyn123
      @tobyn123 5 років тому +5

      @@brianotienotruimp you're not going to have a key more than once as you'll check to see if the key already exists.. if it does simply add to the increment for that letter.

    • @zazethe6553
      @zazethe6553 5 років тому +3

      you dont need to even use a hashmap. you can use the ascii code of a char as a direct index in an array:
      intarray[(int)string.charat(y)] gives each character a unique position in the array. The int values of chars a-z is 97 to 122, and you can cast a char directly to an int.
      public char firstnonrepeating(string searching){
      // index in this array will be the ascii code of each char, value the count
      int[] found = new int[122];
      // index in this array will be the ascii code of each char, value the last index
      int[] lastpos = new int[122];
      for(int j = 0; j < searching.length(); j++){
      found[(int) searching.charAt(j)]++; //count each character
      lastpos[(int) searching.charAt(j)] = j; //store the last index of this char
      }
      int position = searching.length();//keep track of the
      char found = '_';
      //the array will contain all counts, find the one with the smallest position
      for (int i = 97; i

  • @Sir1us1
    @Sir1us1 3 роки тому

    You can actually do it in a single pass if you store the position of the character. Also: you don't need to store the count, just the flag whether it occurs more than once.

  • @JunaidAhmed-jd5kq
    @JunaidAhmed-jd5kq 3 роки тому +3

    Just joined Bachelor's in CS.
    At first thought I know that it can be done in two ways ,
    •First by nested loop , by checking every index, but I know that it will take more time. (Once I got similar problem in Programming contest. I did it by looping, but I got TLE. So later I got to know about Hash Map)
    •Second we can do it by using hash map.

  • @GuRuGeorge03
    @GuRuGeorge03 3 роки тому +1

    This is the first interview question that I have seen that actually has some real world use.

    • @marttielvisto3519
      @marttielvisto3519 3 роки тому

      Where would it be used? Not doubting you I'm just curious

    • @aura4127
      @aura4127 3 роки тому

      @@marttielvisto3519 ^

  • @rc3043
    @rc3043 4 роки тому +4

    NonRepeating and Unique does have a different meaning right? My first (as non english native) was just lookAt [index+1] XD lol

    • @lleytonmorris6305
      @lleytonmorris6305 4 роки тому +1

      I guess it doesn't specify whether or not they have to be "directly repeating" or just "repeating" within the string. I agree though that "Unique" would be a better term to have used.

  • @codesling3421
    @codesling3421 4 роки тому

    Without looking at the video (so his solution may be better than mine).
    Put the characters into a LinkedHashMap where the key is the character and the value is the total occurrences of the character in the string.
    Then, remove any element from the map with a value higher than 1.
    Then, return the first of the remaining entries on the LinkedHashMap.
    (Note: It is important to use a LinkedHashMap since it keeps the order in which the elements were inserted)

  • @dreinax
    @dreinax 4 роки тому +9

    I tried this myself before watching solution. Took me like two hours to create this 60 rows long monster that somehow actually worked, but then I played the rest of the video and couldn't believe how easily it can be solved 😂

    • @ipodtouch470
      @ipodtouch470 3 роки тому

      You'll get better keep practicing

    • @dj_b1627
      @dj_b1627 3 роки тому

      60 rows for what??

  • @Matt23488
    @Matt23488 3 роки тому

    That last solution, where you compare indexOf() to lastIndexOf(), is not O(n). Since both indexOf() and lastIndexOf() both need to loop through the string, and you're calling them on each iteration of the outer loop, you're back to O(n^2), so while the code looks much cleaner and I would prefer it in a situation where string lengths would be guaranteed to be small, it is worth pointing out that it is not an optimal solution in terms of time complexity, and probably wouldn't pass an Amazon interview.

  • @mohycs
    @mohycs 4 роки тому +3

    That intro, the baggy shirt, the monotone. Oh no it’s the coder kid starter pack.

  • @jeffadams1296
    @jeffadams1296 5 років тому

    Proposed solution=
    create empty seenArray
    for each letter, determine if it is already in seenArray,
    if it doesn't already exist, push letter onto [end of] seenArray,
    if if does exist already, remove existing letter from seenArray (don't add current letter to seenArray)
    proceed to next letter for sample.length-1 times
    once end of sample is reached, return seenArray[0]
    Note: I just discovered your channel and I like the content so far. Great job! My software development experience is limited to a few projects and the first few sections of freecodecamp. I haven't covered data structures yet but I've seen a few videos touching on the topic. I still immediately think of stacking with arrays. I could be wrong here but this method seems worth mentioning as I think it should be O(n) with limited space. I'd love it if someone schooled me if I'm misunderstood here. Looking forward to the rest of your content, Nick! keep it coming.

    • @MicLo18751
      @MicLo18751 5 років тому

      Your proposed solution sadly won't work, for example, it will return 'a' for the input string 'aaac'.

  • @kunal_chand
    @kunal_chand 5 років тому +6

    Your video on "How to Crack Google Interview (Complete Guide)" is now private.
    Can you please post it again. It would be really helpful.

  • @backedPOTATOE
    @backedPOTATOE 3 роки тому +1

    Loop through the string with with a for loop --> use the method "lastindexof" with your current character. If the index that the method returns is equal with your current index than the character doesnt repeat. Thats the first solution that came into my mind. And you only have to loop through it once.

    • @backedPOTATOE
      @backedPOTATOE 3 роки тому

      Should wait till the end before commenting... lol

  • @summerxing492
    @summerxing492 5 років тому +10

    Just abt to do this Q n saw urs! Awesome dude!

  • @danny1475369
    @danny1475369 3 роки тому +2

    great vid, there 's an option to use insertion ordered data structure (like dict in python or vector in cpp) and increment the keys after their value passes 1-->O(n)

    • @jonathansaraco
      @jonathansaraco 3 роки тому

      This was similar to my first thought. Define a queue containing characters you've only found once, and as you find a duplicate character, take it out and move it to a set containing characters you've found more than once. I believe that solution is O(n) as well, and it's nice that we don't have to worry about counting. I think I still like the int array solution the most, though.

  • @monoham1
    @monoham1 4 роки тому +19

    how tf are the interview questions this easy!?

    • @sqfzerzefsdf
      @sqfzerzefsdf 4 роки тому +1

      unless they specified what job this is for a coding interview can range from all sorts of coding related jobs, you definitely don't need much more than this if you're just going to be doing some assistance or something

    • @doggo660
      @doggo660 4 роки тому +12

      normally this is a warmup type question. You'd be shocked how many people can't solve a problem like this in linear time.

    • @rhythmpatel5665
      @rhythmpatel5665 4 роки тому

      @@doggo660 I hope so!

    • @dzramen
      @dzramen 4 роки тому

      This was still not an optimal solution. 2 integers could be used to store all of the needed information in their bits. Also, providing information about the actual complexity of the HashMap, which is constant, but not 1, would show that you are a more advanced developer.

    • @chillegaming8250
      @chillegaming8250 4 роки тому

      @@dzramen Could you elaborate a little? Or may be give a link to your solution on leetcode?

  • @domitorid177
    @domitorid177 3 роки тому

    Hey, buddy. In your first "brute force" example you don't have to start with j=0. The situation here is similar to bubble sort, where second loop doesn't need to look for previous elements, because they were handled in previous loops, so make it j=i++

  • @K_R_N.
    @K_R_N. 4 роки тому +7

    Instead of looping through the entire string a second time to find the first unique char, take the index of the first 1 in the char counts array, add the ascii code for 'a' and that's your character. Would be faster as you only have to loop through 26 chars at worst.

    • @makagyngrimm3392
      @makagyngrimm3392 3 роки тому +4

      That would return the front-most letter of the alphabet that occurs once. Not the first letter in the original string that occurs once.

  • @edschaeffer
    @edschaeffer 2 роки тому

    Why the second loop over the string? You could record the index in the hashmap instead of the times it occurs, and if it occurs more than once, replace the index with -1. Then, loop through the keys of the hasmap and record the lowest index.

  • @Lokoislive
    @Lokoislive 5 років тому +12

    I wanted to ask bc my friend told me about it when interviewing, btw this did help me understand what companies want from someone, anyway my friend told me that if they give u a question u already seen and solved that u should tell them, is that a good idea or no??

    • @CknSalad
      @CknSalad 5 років тому +5

      I say it depends how well-rehearsed and familiar you are with the question. If you literally know the exact steps, I would be honest with them, but also be clear with the boundary conditions of your solution. Then maybe, they would ask further constraints to the same problem (any good interviewer should do this) or ask a different problem. The main goal of these interviews is to see how well you can communicate your thought processes and divide a problem into smaller/logical chunks under a time constraint. I think the big mistake a lot of people make is going straight to coding without giving a good big picture step through of the problem and how it can be solved. Implementations can then vary.

  • @lleytonmorris6305
    @lleytonmorris6305 4 роки тому +1

    This solution seems more like it should be "first unique character"
    Also in the case of the the array[26] solution, wouldn't it actually iterate alphabetically meaning you would get the "first unique character alphabetically". If all inputs are alphabetically sorted then this isn't a problem but It doesn't specify that anywhere. I think it would be more safe with using the hashmap

    • @FinBoyXD
      @FinBoyXD 3 роки тому

      No, you dont iterate through the array, the same as you dont iterate through the hashmap. You iterate over the input string only. And with both, hashmap and array[26] you have constant time of getting the value that represents the number of occurrences. In hashmap, you calculate the hashcode, and in the array, you calculate the index with the letters like b - a = 1 for b, d - a = 3 for d etc. Same thing.

  • @MagnusAnand
    @MagnusAnand 5 років тому +3

    When I read Java I understand why people say that Python is more beautiful 😛

    • @notkamui9749
      @notkamui9749 5 років тому

      his code writing style is trash tbh.
      You can do way cleaner than he did, by using foreach loops, or streams

    • @notkamui9749
      @notkamui9749 5 років тому

      for example :
      String s = "aaaabccdeeff";
      return s.toCharArray().stream.filter(c -> s.indexOf(c) == s.lastIndexOf(c)).getFirst().get();
      or even
      String s = "aaaabccdeeff";
      for (char c : s.toCharArray())
      if (s.indexOf(c) == s.lastIndexOf(c))
      return c;
      return '\0';

    • @yrtwo
      @yrtwo 5 років тому +2

      @@notkamui9749 u wouldnt return '_' for the first solution

    • @authenticnaturalnoises
      @authenticnaturalnoises 4 роки тому

      Java is horrible for reading (or working) unless you really have to work with Java as the company requires, otherwise Python is way better to work and read.

    • @VishalPatel_imvishal
      @VishalPatel_imvishal 4 роки тому

      Does programming really matters when solving the problem? What matters it time and space complexity.

  • @govindkrishnalb
    @govindkrishnalb 2 роки тому

    Your thumbnail was so good that i did not need to watch the video to get solution, great job man!

  • @YuzuDrink
    @YuzuDrink 5 років тому +6

    "non-repeating" here seems fairly misrepresentative of what you're actually doing given the rules explained. At best, it's super vague. I would prefer the word "unique", myself. I could MAYBE consider "non-repeated"; but "repeating" implies that the letter is the same in the order given. Not really YOUR problem, I guess; and as long as the rules are there it doesn't matter too much. Just seemed weird.

    • @tashikrtv6878
      @tashikrtv6878 5 років тому +3

      Man you're dumb

    • @augustvctjuh8423
      @augustvctjuh8423 5 років тому +1

      I agree that "unique" would be less unambiguous to use. However, "non-repeating" is not necessarily incorrect. I think they consider a character being a repetition of an earlier character to count as "repeating".

    • @camronconway439
      @camronconway439 5 років тому +2

      Agreed. I initially interpreted the scenario by thinking repeating was only if it was sequentially repeated, not that repeating meant no duplication of a character in the entirety of the string. (Past tense of the verb repeated vs active verbiage use of repeating is interpreted differently in my mind).
      I.e. aabcd would return a, but abcabd should also return a as a was not directly followed by another a. So I think first unique character, or first character that has a count = 1, or something along those lines would be better in giving a firmer grasp of the scenario presented.

  • @alexanderpoplawski577
    @alexanderpoplawski577 5 років тому +1

    The third example with the 26 character array wouldn't work. It would return the lowest character in the alphabet non repeating, not the first.

    • @NickWhite
      @NickWhite  5 років тому

      it does work! think about it a little more! passes all test cases and submits successfully

    • @alexanderpoplawski577
      @alexanderpoplawski577 5 років тому

      @@NickWhite Is it not only because your string is in alphabetical order?

    • @alexanderpoplawski577
      @alexanderpoplawski577 5 років тому

      @@NickWhite I rewatched the video and found, that you are traversing over the string in the second loop. This does work. Sorry

  • @tommi1654
    @tommi1654 5 років тому +5

    What about this solution (only loops once):
    string = list('abacabad')
    not_repeating = []
    visited = []
    for i in string:
    if i not in visited:
    not_repeating.append(i)
    visited.append(i)
    else:
    if i in not_repeating:
    not_repeating.remove(i)
    if not not_repeating: # if not_repeating is empty
    print('_')
    else:
    print(not_repeating[0])
    >>> c

    • @amirberkani8492
      @amirberkani8492 5 років тому

      perfect;

    • @torontoTamilan7
      @torontoTamilan7 5 років тому

      I want you to teach me your sorceries ,Master.

    • @torontoTamilan7
      @torontoTamilan7 5 років тому

      Only one thing ,try doing it in c ,c++,or java

    • @890popbox
      @890popbox 5 років тому +1

      This solution is good if a lot of the characters in the string are not repeated consecutively, or there is not a unique character within the string.
      Note: This solution is actually O(N^2) as it loops through a list again, and we have to store two more lists than needed to solve this problem.

    • @amirberkani8492
      @amirberkani8492 5 років тому

      @@890popbox dude it loops only once

  • @MrVikram0001
    @MrVikram0001 4 роки тому

    In the map, first time add the Index value of a character as a value to key (character), and later instead of adding a count of occurrence, just make the value of a key (character) as -1 if it's repeated. Now iterate over unique keys from the map and not input array (so it will be less in number as compared to original string ) and check for lower index character .. here you got the solution.

  • @AmanVerma-lt7px
    @AmanVerma-lt7px 5 років тому +3

    the new video format is much better

  • @lool8421
    @lool8421 3 роки тому

    for non-repeating characters, my idea to optimize stuff is just scan the string when finds a letter, after scanning it turns all duplicates into let's say zeroes, that are simply ignored, so if you have aaabccc..., it just scans the entire string once for a and once for c, however i think it would go below O(n*log(n))

  • @eimantasg2055
    @eimantasg2055 5 років тому +3

    I dont know if only Python has count method? In python i would do like this: for loop (for char in string) then if string.count(char) == 1: return char, else string.replace(char,'')

    • @skyisblue3847
      @skyisblue3847 5 років тому +1

      collections.Counter()

    • @PrevalentAA
      @PrevalentAA 5 років тому +1

      You can do it in python with storing occurences in a tuple then turn the tuple into an array(that only takes a value once ) and make it print the first corresponding character from the string that has occurence equal to 1

  • @Salsuero
    @Salsuero 3 роки тому

    Why not create a second array that populates with the letter found for each new index position and then loop through the first array (the one with the number of hits) the second time instead of the entire string? You'd only have a maximum of 26 items to loop through in the array as opposed to the possible 100,000 duplicate characters in the original string. Once you find the first index with a 1, you check the second array for the letter that was originally found for that index position.