Counting Sort: An Exploration of Sorting Special Input In Linear Time

Поділитися
Вставка
  • Опубліковано 22 вер 2024

КОМЕНТАРІ • 162

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

    Table of Contents:
    Introducing Counting Sort 0:00 - 2:08
    Walking Through The Algorithm 2:08 - 3:18
    Step 1: Initialize Occurrence Array 3:18 - 3:27
    Step 2: Count Occurrence In The Original Array 3:27 - 4:34
    Step 3: Aggregation of Occurrences 4:34 - 6:28
    Why Did We Just Do That? 6:28 - 7:54
    Step 4: Placements 7:54 - 10:14
    Sorting Finished. 10:14 - 11:52
    Analyzing Counting Sort 11:52 - 15:43
    We Get The Final Bound 15:43 - 16:10
    Wrap Up 16:10 - 17:08
    The code for the problem is in the description. Fully commented for teaching purposes.

    • @AnshulSharma-vw9wu
      @AnshulSharma-vw9wu 4 роки тому +1

      Back To Back SWE
      Hi ,
      I have seen many of your videos those are really good . In this one , I would like to understand why we need to do summation .
      I have tried to come up below solution without doing summation it passed all the testcases on leetcode . Am I missing something
      class Solution {
      public List sortArray(int[] nums) {
      if(nums == null || nums.length == 0){
      return null;
      }
      return countingSort(nums);
      }
      private List countingSort(int[] nums) {
      Integer maxNum = null;
      Integer minNum = null;
      int [] countingSortPositive = null;
      int [] countingSortNegative = null ;
      for (int index = 0; index < nums.length; index++) {
      int value = nums[index];
      if(value >=0){
      if(maxNum == null){
      maxNum = value;
      }else{
      maxNum = Math.max(maxNum, value);
      }
      }else {
      if(minNum == null){
      minNum = value;
      }else{
      minNum = Math.min(minNum, value);
      }
      }
      }
      if(minNum != null){
      countingSortNegative = new int[Math.abs(minNum) + 1];
      }
      if(maxNum != null){
      countingSortPositive = new int[maxNum + 1];
      }
      for (int i = 0; i < nums.length; i++) {
      int value = nums[i];
      if(value >=0){
      countingSortPositive[value]+= 1;
      }else {
      countingSortNegative[Math.abs(value)]+=1;
      }
      }
      List list = new ArrayList();
      if(countingSortNegative != null && countingSortNegative.length > 0){
      for (int i = countingSortNegative.length -1 ; i >=0; i--) {
      if(countingSortNegative[i] != 0){
      for (int j = 0; j < countingSortNegative[i]; j++) {
      list.add(-i);
      }
      }
      }
      }
      if(countingSortPositive != null && countingSortPositive.length > 0){
      for (int i = 0; i < countingSortPositive.length; i++) {
      if(countingSortPositive[i] != 0){
      for (int j = 0; j < countingSortPositive[i]; j++) {
      list.add(i);
      }
      }
      }
      }
      return list;
      }
      }

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

      I haven't replied to this for a bit, replying to close this out in my "unresponded to comments" feed.

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

      Sorry to be so offtopic but does anybody know a trick to get back into an instagram account?
      I somehow lost the login password. I would love any tips you can give me.

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

    Landed a job last month and relied on your videos a lot. Just donated some money to your Patreon. Thanks for everything!

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

    Nice explanation. You could've picked other example - the one that contains duplicated elements. It would make it easier to understand why the running sum array is needed.

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

      The running sum step is not necessary, it is only one version of counting sort (the more commonly seen one which is why I covered it). You could just create an occurrence array and from there go straight to placement. The asymptotic complexity is still the same.
      Why would duplicated elements necessitate the aggregation step?

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

      @@BackToBackSWE you're right, it's possible to do it without performing a sumation if we're sorting just numbers like in your video. Although I still think it makes it easier to understand if you have duplicates in the array, see this visualization: ua-cam.com/video/7zuGmKfUt7s/v-deo.html

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

      Yes, that's the version we covered ... I'm still confused on how duplicates change anything. We would always be sorting positive integers (whether we codify actual objects/any other non-integer value we want to sort into an integer mapping). Can you clarify, I must be missing something

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

      @@BackToBackSWE ok maybe it was just me but after watching your video I wasn't completely sure why running sum step was needed. But if you perform this algorithm on an array with duplicates, you see that running sum array is actually useful, it helps to place a correct amount of a given element in the final array. Sorry for not being clear enough before :)
      As for the difference between sorting just integers vs some other structures, see this post because it explains it a lot better than I could (it also touches the topic of cumulative sum): stackoverflow.com/a/32235015

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

      @@mzmzgreen Ahhhhhh, gotcha. That link cleared it all up. Yes, you are right, that is why the aggregation sum step is needed (in the case we are not sorting just raw numbers) - so we can go to the original array and place objects in the right index (and at that point the 'count' array will be a literal "guide" for us to know where to put what based on its key integer value).
      Dang, I learned something, thanks

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

    Is it just me or is this algorithm just confusing in general? I reckon you did a good job explaining it as a simply as possible! No matter what resource I look at this algorithm just does not make sense to me hahah.

  • @100_swastiksanyal5
    @100_swastiksanyal5 Рік тому

    You explain in a very smooth manner. Your videos are so soothing to watch. you are so calm

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

    We can actually modify the counting sort to even include -ve integers as well. For that we can use extra space in the same array with one partition for +ve integers and one for -ve. and when we finally count the numbers we start from the 2nd partition (which has negative integers stored only their +ve magnitude which will be converted to -ve when producing output from the partition 2) and then after completing it we use the first partition for +ve integers.

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

    I don't skip your videos that's how I can help you and I suggest other to do this .... Thanks bro ... You are one of the best computer teacher

  • @atvonguyentien5726
    @atvonguyentien5726 Рік тому

    You know what? You're so good at teaching. Let keep the good work and your effort will definitely paid off sooner or later.

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

    I've seen many implementations but only this one matches with my uni's and is fairly understandable. ^^ Thank you, keep up the good work !

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

      nice

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

      it does not work for duplicate numbers i think.. Since there are no negative indices any way pls tell me how to implement this for negative numbers as well.

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

      ​@@shreevatsalamborghin int max = Arrays.stream(a).max().getAsInt();
      int min = Arrays.stream(a).min().getAsInt();
      int range = max-min+1;
      int [] count = new int[range];
      int [] output= new int[a.length];

      //store count of each character
      for(int i=0;i

  • @Charles-rn3ke
    @Charles-rn3ke 5 років тому +16

    The example you use is too special and not general

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

      Yeah, my bad. Code in description to clarify but yeah, my fault for that, I got lazy.

  • @samuelbarks1
    @samuelbarks1 4 роки тому +5

    in CLRS it says that K represents the range of the input from (O, K) not how many unique elements there are

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

    Very underrated educational content. I just subscribed and hope to learn more programming concepts. Keep it up

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

    You have a talent in teaching. I was so confused by watching other videos, your video was the easiest to understand.

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

    Can't believe it took me so long to find you. Your videos are the best.!!

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

    I think the terminology of prefix sums is used widely, i was confused with running sums, but in the end I got it that it was actually prefix sums that I learned for other algorithm before.

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

      By the way prefix sums ONLY NEEDED WHEN WE HAVE DUPLICATE VALUES IN THE ORIGINAL ARRAY to avoid extra nested loop while reconstruction your sorted arrays.

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

      And you forgot to mention why we started reconstruction the sorted array by traversing from the end of the array. The reason is to preserve the STABILITY of the array. You can start from the beginning, in that case the stability of the array is not preserverd

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

      nice

  • @bassemsamuel3249
    @bassemsamuel3249 8 місяців тому

    Thankss a lot for this explanation really clicked for me!

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

    Has the code been removed?

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

      The repository is deprecated - we only maintain backtobackswe.com now.

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

    Thanks so much for your videos to help me understand BFS and DFS, now you are my go to channel when I learn new algorithms

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

    I love your videos! I'm taking algorithm design course and you explain things better than my prof lol

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

    Cant wait for you to hit 100k subscribers. You'll get it done in no time props to you man

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

    great video. been stuck on this for a long time

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

    Can you explain why we iterate backwards while doing placements in the original array?

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

      It is just the more common implementation, you can go the other way too

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

      @@BackToBackSWE It also makes the implementation of a sorting algorithm stable if you iterate backwards

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

    i gotta say this video is awesome i've seen a few videos and non of theme were this awesome

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

    Great explanation Ben! One can easily follow :). do you have radix sort explanation video created? if not, can you please create one for Radix sort ?

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

      Thanks and I almost made one but go too busy during the semester, yeah i can

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

      @@BackToBackSWE nice. Looking forward to it! thanks Ben for all great videos. One thing that would be great to include in that video would be when should you use Counting sort vs Radix sort? I figured when you have input like [ 0, 11111111111111111] counting sort would perform slow vs it would be very easy for radix sort.

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

    This video is amazing ,good explanation.

  • @antonmyshenin9424
    @antonmyshenin9424 Рік тому

    Given k - unique values and n - all values, we could conclude that k

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

    great explanation. easy to understand.

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

    You should have a zero and well other numbers that aren't 1 in your c array.
    Any idea on how to write code to sort in
    descending order (exam tomorrow)?

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

      how was the exam - got to this late

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

      I don't think I passed. I guess they thought we would all cheat and made it extra hard.
      I figured it out in case this could help someone:
      To order in non increasing manner:
      For i=k-1 down to 0 {
      C[i] = C[i] + C[i+1]
      }
      K being the length of the C array.

  • @xuehaizhou8335
    @xuehaizhou8335 4 роки тому +5

    Your explanation is pretty good, but the example you use is too simple which occurs some confusion. Thank you anyways.

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

    We go from back to make sure that the sorted array is stable. We are basically placing the last occurence of the element in the last possible index it can be placed at.

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

    I got it , I got it , I got it , I got it , Thanks 🔥

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

    brilliant explanation, thank you

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

    I love your videos! Great explanation

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

    I am now at 3:56 . Everything still clear . Thanks

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

    This is a very good video. However, if the example is an array with duplicates, it would be better. Thanks

  • @n.h.son1902
    @n.h.son1902 3 місяці тому

    8:02, why do we move backwards in the array arr? Is there any reason behind this? Why not moving forwards?

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

    Great explanation!

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

    Great explanation, but I with you'd use different test set as an example, it does not show how algorithm behaves in case of duplicates.

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

    I think you should have explained the algorithm further by showing why exactly (after performing the accumulative 'running sum') does each index denote the last possible occurrence of value (i). Great video nonetheless, thank you!

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

    any plans for tackling 621. Task Scheduler in leetcode?

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

      Not sure when I'll do that, I'm just winging it right now

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

    Your videos are awesome, great explanation. I Have a few questions not related to this video but for interview preparation.
    I already did about 70 leet code but after a month when I look at the same problem I solved it I don't remember which algorithm I used and it takes me 30 mins or one hour to solve it again. Is this normal? Can you please guide me in these 3 questions:
    1. When were you looking at the correct solution -- before you began the problem when you got stuck, only after struggling to solve it yourself? How long until you would look at the solution, typically?
    2. What would you do after you'd not solved the problem, but looked at the answer?
    3. What would you do after you did solve a problem?

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

      yes that's normal - the amount of leetcode you do has a very loose correlation to preparedness. It's not about problem count - it's about topic comprehension.
      1.) It depends, when studying you may just fundamentally not have the toolset to solve a problem, so trying can waste your time if even the brute force is locked from you. A problem like this is kind of bad since it doesn't demonstrate critical thinking...but you can often recognize it. If you know you can brute force you do that and then maybe give it 10-20 min beore you give up? really up to judgement.
      2.) I'd want to deeply understand the solution, why it works, and the principles it has taught me to apply elsewhere. Some problems are good for this and some are less useful.
      3.) I'd check the solutions to see if there was a more optimal way.

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

    Great video! but I don't seem to find the code? Where is it?

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

      Repository is deprecated and no longer maintained

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

    Subbed. Thank you boss. Ur gono b a star

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

    Why do you start from the last item in the array instead of the first item for the final loop?

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

    Is there any particular reason as to why we are trying to find positions for our numbers in the given array from the last? We can do a normal traversal of the given array right? I'm talking about the last placement and decrement of count step.

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

      yeah we can

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

      Actually found out the reason:
      1. When we use counting sort as a subroutine in radix sort, we need to maintain the relative ordering, there we must traverse from the back otherwise, radix sort fails.
      That's the reason! Love your videos man. Thanks.

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

      @@arunm619 nice

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

    TYSM

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

    Dont we need two for loops(i mean nested) to get the occerences?

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

      I don't remember the code for this to be honest

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

    Thank you!

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

    Good video and thanks for that. But wish you had used a better example. Array of size 5, indices 0-4, array values 0-4. Simply too confusing and required several iterations to get it.

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

      yeah I know - I have a memory of every video I didn't make all I wished it could be. This is one of them

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

    "At the end of this, we are going to generalize this to mapping anything to an integer."
    Where is this done?

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

      I think I forgot, ya got me. But yeah, it is as stated, if we can map an object to an integer (or establish that relationship in any way) then we can sort the data based on those integer mappings. I just forgot to do an example of it but it is the same thing.

  • @akashjain2990
    @akashjain2990 7 місяців тому

    Why do you need to traverse backwards for placement?

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

    Thank you.

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

    i guess its important to emphasize that the mechanism is at is, because an element can also have multiple occurrences in the initial array.. then its important to have the intermediate running sum, starting from the back.. because the order needs to be maintained (FIFO), even if the numbers are the same

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

    Hi, amazing video, but I have one question:
    for this init array => [ 0, 200, 5000] => k would be 3 or 5001?

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

      I don't remember to be honest, I'd have to recap on counting sort

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

      I think it's 3, from how I understood it

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

      k would represent the range of nos so max - min +1 = 5001

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

      5001 , here counting sort is not efficient

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

    homie can u drop new videos on Rod cutting dynamic programming etc.

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

    thanks

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

    Hi! I love your videos! Where exactly is the code you reference to be in the description? Is it in the website that is linked?

    • @BackToBackSWE
      @BackToBackSWE  Рік тому

      You can check out the code repository on backtobackswe.com/

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

    I'm confused on why we say n+k instead of n, because we know for sure k will be smaller or equal to n (worst case equal to n), in that case, shouldn't we ignore it?

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

      Correct, I think it is a matter of specificity because they are different parameters.
      Asymptotic bounds do ignore constants (by their very definition of picking an arbitrary c to multiply by f(n) to bound T(n)), but even if n upper bounds k, it is still not a constant. It should be considered in the asymptotic notation since it is another parameter that an external caller can modulate.
      The end behavior is linear through and through, hence "linear time".

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

      @@BackToBackSWE Thanks a lot for the detailed reply!

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

    Wow tHANKs!

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

    Hi there! I've just found this video and its helping me a lot! But I have a doubt. If I don't know the size k of my count array is it still worth to use counting sort? I have an 10^6 numbers in my vector but I don't know their sizes.

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

      im not sure, I forgot counting sort since I shot this, I need a refresher

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

      Counting sort is most effective when
      1) You know the range your values will be in
      2) You're comfortable with the space implications of building a count array of the size of the range. (Space tradeoff)
      In this case it seems you're not sure what range your values may be in. Moreover, even if you were, 10^6 values would mean a lot of space and time to build a count array (Assuming little to no duplicate values i.e all 10^6 are fairly unique.)

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

      @@bolu3307 thanks

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

    bro I cannot find selection sort on your channel? i remember you had it

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

    Can you do a video on Radix Sort please?

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

    15:45
    the symbol looks like Baymax from Big Hero 6 lmao

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

    Your explanation of K is wrong. K is not the number of unique values in the input array. If it were so, for example, for an input array [1,0,2,999], your count array would be [0,0,0,0] i.e have index 0 to 3. This will not work as the program will not be able to access count[999] and increment occurrences. K is the max value in the input array. So the count array should, in this case, be of size -999- 1000
    edit: size = k+1 = 1000

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

      Did I say that? Don't remember, if so thanks for the catch.

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

      @@BackToBackSWE np. between 2:21-2:26.

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

    what about duplicate value in the array? I cannot figure it out with this algorithm.

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

    dude i fucjiubng love you

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

    Confusing, should use letters instead, don't know if you are referring to the number or the index. Didn't even show duplicate case.

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

    But what if we do not get k

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

    final array index can start from0/1

  • @epiclasersharks1866
    @epiclasersharks1866 Рік тому

    hero

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

    2 arrays and cumulative summing for sorting simple integers is a bit of an overkill. it's good for keeping the sorting stable, but stability is meaningless when sorting integers. besides, since the elements are unique, counting is unnecessary, so the example is probably not the best (woulda been great for radix sort).

  • @MIRMOHAMMADREZAHEIDARZADNAMIN
    @MIRMOHAMMADREZAHEIDARZADNAMIN 4 місяці тому

    ZERO is a non negative integer not a positive integer. The upper bound for the second and forth summation should be n not n-1.
    You are not a professor my friend, when you don't know something correctly, don't make such video clips and waste our time.

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

    Please stop teaching, teaching is an art, and it is just your assumption that you can teach. + even if you want to do it, prepare on paper first and then record. Thank you