Data structures and algorithms problems in C++ using STL
techiedelight.com
techiedelight.com
Here's a couple innocent-looking special cases that are still surprisingly hard:
1) Given an array [a1, a2, ..., an, b1, b2, ..., bn], rearrange it into [a1, b1, a2, b2, ..., an, bn] using O(n) time and O(1) extra space.
2) Given an array of zeroes and ones, sort it stably using O(n) time and O(1) extra space.
I'd be very interested to hear about any advances in this area.
and most importantly:
b) you might not have extra space. For example, if you are implementing an out of core sort (i.e. sorting huge on-disk datasets), you want to maximize the size of the chunk you will sort in memory and do not want to waste any memory for the temporary storage. (this is related to locality of reference of course, you can a make similar argument for out-of-cache sorting).
I noticed the problem is relatively easy if you're dealing with a linked list instead of an array, because you can easily move elements around. If there's some way to amortize that in the array case...
Try indexing from 0 instead of 1 if you're not. Then the cycle containing 1 will start with (1, 2, 4, 8, ...). What happens when it wraps around?
I'm missing something here. If the array's values truly are all in {0,1}, then all the zeroes are indistinguishable and you get stability for free (same for the ones).
mysort all01list = let ones = sum all01list in replicate (length all01list - ones) 0 ++ replicate ones 1I would be interested in hearing recommendations for other such sites that specifically discuss the methodology for approaching these problems.
Geeksforgeeks.com is another such resource for learning the approaches as well but I would be curious to hear any other suggestions as well.
Edit: see comment below for why it actually is O(n) and not O(n logk) as I had thought.
std::nth_element is typically implemented using a fancy version of quickselect called introselect. You can imagine quickselect as a version of quicksort where the recursive call is only executed on the side which contains the element. Introselect adds some fanciness to ensure worst-case linear running time if quickselect takes too long (bad pivot selection).
- choose a pivot p randomly from the elements
- partition into elements <= p and > p. This takes time O(n).
- if the number of elements <= p is at most k (the rank of the element we want), do a recursive call on these elements. Otherwise recurse on the other elements (those >p).
Because a random pivot splits the elements well enough most of the time, this has an expected running time of O(n): 1 + ½ + ¼ + ⅛ + … < 2 in the best case, and similar constants if the partitioning is a little worse. But in the worst case, when the pivot is the smallest/largest element in each iteration, it's O(n²). That's where the fanciness of introselect comes in: if quickselect doesn't converge, it switches to an algorithm with worst-case O(n) time, which is slower in most cases but saves the day when quickselect has trouble.
This is interesting I had not heard of introselect before, I will have to read up on this.
Can you elaborate a little bit, specifically how selection algorithms help reduce "chatter" in distributed systems? I am not familiar with this and this sounds like an interesting context.
I have heard of Merkle Trees for similar but that's obviously hashing and not selection algorithms, or is there some connection I am not making?
It's hairier than a partial quicksort, but (if you erase the proof and weigh the chalk dust) guaranteed linear time.
On an unrelated note, I was once asked to prove the upper bound for median of median on an interview...
Sure it is. It's as much as showcase of practical applications of the STL as it is of algorithms. Any algorithms book has implementations, the great thing about this site is that it shows you how to use the STL in real world applications.
Then, make sure you use std::make_unique or std::make_shared rather than operator new if you are going for a C++ job.
Which modern language should I try if the first thing I miss in a language is the STL and the C-like syntax?
OCaml I guess isn't that modern but they did just add First Class modules [1].
[1]: https://realworldocaml.org/v1/en/html/first-class-modules.ht...
It has a ton of warts and complexity but it also has the features you need. If you program in C++ you can have simple solutions 95% of the time and when the intrinsic complexity is higher the language has the tools to save the day. Many other languages will solve the simple parts slightly cleaner but the complexity explodes on the difficult bits.
However if you are looking for fun I really like Rust, it has a nice c++ feel without having to worry so much. Personally I still think it is a bit too new for "enterprise coding" but it is maturing nicely and learning it will really teach you a lot.
To answer the question, there are many general books on algorithm design that would be appropriate for any language.
"Introduction to Algorithms"
https://www.amazon.com/Introduction-Algorithms-Thomas-H-Corm...
I don't see any links to it from any of Skiena's or the publisher's webpages, so it's not clear how legitimate it is.
Incidentally, I wouldn't really suggest Skiena as an alternative to Cormen et al; they're extremely different in style and content, and in situations where you need one of them the other probably won't help you. I recommend getting both. (For more verbosity on this, see my review of the first edition of Skiena's book at https://www.mccaughan.org.uk/g/books/alg-design.html .)
I agree with you. Get both.
It's free. It doesn't have the formalism of CLRS which some might not like but its still a great practical resource if you want Python.
C++98 or
C++03 or
C++11 or
C++14 or
C++11 or
C++17 or
C++20 ?It doesn't appear to use new language features, only some library things like std::unordered_map, from what I gathered in a quick look. Most things will probably work just fine with C++03.
Then we would need to know which of the following versions is being used:
Python 1.0 - January 1994
Python 1.5 - December 31, 1997
Python 1.6 - September 5, 2000
Python 2.0 - October 16, 2000
Python 2.1 - April 17, 2001
Python 2.2 - December 21, 2001
Python 2.3 - July 29, 2003
Python 2.4 - November 30, 2004
Python 2.5 - September 19, 2006
Python 2.6 - October 1, 2008
Python 2.7 - July 3, 2010
Python 3.0 - December 3, 2008
Python 3.1 - June 27, 2009
Python 3.2 - February 20, 2011
Python 3.3 - September 29, 2012
Python 3.4 - March 16, 2014
Python 3.5 - September 13, 2015
Python 3.6 - December 23, 2016
And for extra fun we can also add PyPy, CPython, IronPython, MicroPython, .... into the mix.I can gladly play this game with any other programming language.
Languages that people care about, get new versions all the time, and not all tooling implementations or developers catch up at the same time.
It is part of our job to deal with it.