Edit: curiosity got me looking at this for Python, with an answer of "it depends, and both have correct aspects" based on Python's implementation [1]. The hashing varies by string length, the lookup is fixed unless there's a collision and probing, probing will be minimized by growing the dictionary as items are added. In any case, better than O(n) but worse than O(1) and with some possible slowdowns during loading unless you can set an expected final size during initialization.
Edit again: since I brought it up, turns out initialization doesn't really matter, resizing is not a speed factor. Relevant discussion starts from https://stackoverflow.com/questions/1298636/how-to-set-initi...
[1] http://www.laurentluce.com/posts/python-dictionary-implement...
What you just described is "average" not "amortized". Amortized does not mean "across a set of representative inputs", it means "through time, even if given the same input repeatedly".
Amortized complexity is tricky sometimes. For instance, in a data structure storing a binary integer and allowing an increment operation, the number of bits flipped is amortized O(1). The same is true if the only operation is decrement. Neither is true if you have both increment and decrement!
Another example: you can change the accounting to make things amortized lower cost. For instance, a heap (aka implicit priority queue) can be said to have O(1) deleteMin by simply ascribing an extra O(log n) cost to each insert. In fact, you can say deleteMin has O(0) cost! An example of this being done in the literature is https://arxiv.org/abs/0903.4130, "Pairing Heaps with Costless Meld", by Amr Elmasry.
So many problems...
tl;dr:
1) Interviewer insists that an operation must be n^2 "because it has a nested loop" even though the nested loops are only iterating over their own subset of the master string.
2) Interviewer refuses literally any test that would help decide which of us is right.
3) Interviewer turns out to not even understand the concept of resolving disagreements by appealing to agreed-upon facts, insisting that he would only be convinced by the absence of a nested loop (i.e. talking about some other algorithm).
4) Interviewer is five-year backend lead.
5) Interviewer vetoes me from the rest of the process purely because of that disagreement.
6) Because I thought I was going insane, I implemented it at home and ran the problem with different sizes and the run time with up as O(n) like clockwork.
[1] It's okay, I'm fine with people knowning and have outed myself elsewhere: https://news.ycombinator.com/item?id=6070001
That's a wonderful description of an attitude I have encountered many times.