DSC 40B

Problems tagged with "hashing"

Problem #174

Tags: hashing

Suppose \(T\) is a hash table of size 100 (that is, it has 100 bins). 300 elements are inserted into the hash table using a hash function that satisfies the uniform hashing assumption (that is, any element is equally-likely to hash into any bin). What is the expected number of elements in the first bin?

Solution

3

Problem #175

Tags: hashing

Suppose a hash table is constructed so that collisions are resolved through chaining. The hash table has \(10\) bins, and 100 items are inserted into the hash table.

True or False: it is possible for one of the bins to contain all 100 items.

True False
Solution

True.

Chaining places no limit on how many items a bin can hold, so if the hash function sends every item to the same bin (for instance, a bad hash function like \(h(x) = 0\), or just unlucky keys that all collide), that bin will contain all 100 items. This is the worst case for a hash table, and it makes membership queries take \(\Theta(n)\) time.

Problem #176

Tags: hashing

Assume that a hash table is implemented using chaining to resolve collisions. The hash table stores \(n\) numbers.

Suppose a membership query is made for 42. True or False: more than one bin in the hash table may be checked with a linear search during the query.

True False
Solution

False.

The query computes the hash of 42, which determines exactly one bin, and only that bin's chain is searched. If 42 is in the table at all, it must be in that bin, so there is no reason to look anywhere else.

Problem #177

Tags: hashing

Suppose a hash table is constructed using linked lists to store the data within each bin, and that collisions are resolved by chaining. What is the worst case time complexity of inserting a new element into the hash table? You may assume that the hash table will not need to be resized, and that evaluating the hash function takes \(\Theta(1)\) time.

Solution

\(\Theta(1)\). Inserting an item into a hash table takes two steps: first, we hash the item to find its bin -- this takes \(\Theta(1)\) time. Next, we actually insert the item into that bin. When we use chaining, we do this by appending the item to the linked list containing that bins elements. Appending to a linked list takes \(\Theta(1)\) time, and so overall this takes \(\Theta(1)\).

Problem #178

Tags: hashing

Suppose a hash table is constructed using linked lists to store the data within each bin, and that collisions are resolved by chaining. Suppose \(n\) elements have been inserted into the hash table. What is the worst case time complexity of querying whether an object exists within the hash table? You may assume that the hash table will not need to be resized, and that evaluating the hash function takes \(\Theta(1)\) time.

Solution

\(\Theta(n)\). Remember: in the worst case, all of the elements hashed to the same bin, and our query leads us to perform a linear search in that bin, taking linear time.

Problem #179

Tags: hashing

Suppose we are building a hash table to store numbers. Our hash table will have 1000 bins. True or false: \(f(x) = x \% 2\) is a good hash function. Here, \(x \% 2\) returns the remainder after dividing \(x\) by 2.

Solution

False. \(x \% 2\) is not a good hash function because the outcome is either 0 or 1. All the elements will be hashed into bin 0 or bin 1. This hash function doesn't utilize all bins evenly.

Problem #180

Tags: hashing

Suppose you insert 11 elements into a hash table with 20 bins. True or False: there must exist exactly 9 empty bins, no more, no less, since the number of elements being hashed is less than the number of bins in the hash table by nine.

Solution

False. The key word here is exactly. It is tempting to think that the all 11 elements were distributed evenly, with one per bin, leaving the other 9 bins all empty. But this isn't necessary -- all of the elements might have hashed to the same bin, for example.

Problem #181

Tags: hashing

Consider the code below:

def intersection(A, B):
    common = set()
    for x in A:
        if x in B:
            common.add(x)
    return common

What is the expected time complexity of this code if A and B are Python sets (hash tables) with \(n\) elements each? State your answer as a function of \(n\) using asymptotic notation. You may assume that the hash function used is ``good'' in that it hashes evenly (that is, it satisfies the simple universal hashing assumption).

Solution

\(\Theta(n)\)

Problem #182

Tags: hashing

In the problem below, suppose arr is an array of \(n\) integers. What is the expected time complexity of the code below? Write your answer using asymptotic notation as a function of \(n\).

Remember: set is implemented using a hash table. You may assume that the hash table is large enough to store all of th numbers without needing to resize.

def find_duplicates(arr):
    seen = set()
    duplicates = set()
    for num in arr:
        if num in seen:
            duplicates.add(num)
        else:
            seen.add(num)
    return duplicates
Solution

\(\Theta(n)\)

Problem #183

Tags: hashing

What is the expected time complexity of the code shown below, assuming that numbers is a Python list? Express your answer as a function of \(n\) using asymptotic notation (e.g., \(\Theta(n)\)).

def foo(numbers):
    """Assume that `numbers` is a list containing n numbers."""
    # counts is a Python dictionary, which is implemented using hash table
    counts = {}
    for x in numbers:
        for y in numbers:
            diff = abs(x - y)
            if diff not in counts:
                counts[diff] = 1
            else:
                counts[diff] = counts[diff] + 1
    return counts
Solution

\(\Theta(n^2)\)

Problem #184

Tags: hashing

Suppose a hash table with \(n/2\) bins stores \(n\) elements, and suppose that when the next element is inserted into the hash table, a ``grow'' will be triggered. That is, the insertion will cause the hash table to resize to \(n\) bins containing the same \(n + 1\) elements, plus the newly-added element.

What will be the time complexity of this single insertion operation that causes the table to grow?

Solution

\(\Theta(n)\)

Problem #185

Tags: hashing

Suppose a hash table in constructed so that collisions are resolved through chaining. The hash table has a number of bins \(k\) that is \(\Theta(n)\), where \(n\) is the number of elements being stored in the hash table; that is, the hash table grows as more elements are inserted.

Suppose the hash function uses only the first \(k / 2\) bins of the hash table, but appears to hash items into these bins evenly.

What is the expected time complexity of a membership query on this hash table? State your answer in asymptotic notation in terms of the number of elements in the hash table, \(n\).

Solution

\(\Theta(1)\) Since only \(k/2\) bins are being used, the expected number of elements within each bin is \(n / (k/2) = 2n / k\). But since \(k = \Theta(n)\), this is just \(\Theta(1)\).

Problem #186

Tags: hashing

Suppose you will be receiving a stream of numbers, one by one, and you wish to keep track of the largest number seen so far. You will not need to perform membership queries. What should you do?

Solution

Don't store the numbers at all. To keep track of the maximum, we only need to remember the largest number seen so far; when a new number arrives, we compare it to the current maximum and update if it is larger. This takes \(\Theta(1)\) time per number and \(\Theta(1)\) memory, whereas every data structure would use \(\Theta(n)\) memory and at least as much time.

Problem #187

Tags: hashing, binary search trees

Suppose you need to keep track of a large dynamic collection of numbers. You will be performing n insertions, n deletions, and a very small number of queries for the maximum element in the collection. You will also be performing membership queries.

Which data structure should you use? You may assume that time complexity is the most important criterion.

Solution

A hash table. In a hash table, insertions and deletions take constant time (on average), while a query for the maximum element takes \(\Theta(n)\). Since we are running only a constant number of max queries, they take \(\Theta(n)\) time in total, and the \(n\) insertions and \(n\) deletions also take \(\Theta(n)\) time in total. In a balanced BST, all of these operations take \(\Theta(\log n)\), which means running n insertions and deletions will be \(\Theta(n \log n)\) -- slower than a hash table.

Problem #188

Tags: hashing, binary search trees

Suppose you need to keep track of a large dynamic collection of numbers. The three most common operations you will be performing are insertions, deletions, and queries for the maximum element in the collection. You may assume that the number of maximum queries you will be making is close to the number of insertions/deletions. You will also be performing membership queries.

Which data structure should you use? You may assume that time complexity is the most important criterion.

Solution

A self-balancing binary search tree. The key is that we're allowing deletions and max queries. If we delete the maximum, we'll need to find the next maximum upon our next query. In a hash table and unsorted array, this will take linear time. In a sorted array, finding the next max takes constant time -- but insertion and deletion potentially take linear time. In a balanced BST, all of these operations take \(\Theta(\log n)\) in the worst case -- this is because a BST essentially keeps nodes in sorted order.