Using a hashtable, you can solve this in $O(n)$ expected time, as follows:
- Fill a hashtable $H$ with the given numbers.
- Go over all numbers in the list. For each number $x$, if $x-D \notin H$:
- Go over the numbers $x + D, x + 2D, x + 3D, \ldots$ until you find a number not in $H$.
The running time of the first step is $O(n)$. As for the second step, the potentially expensive step is the sub-step. However, in this sub-step we go over each element in the list at most once (we check $y$ only for $x = y-aD$, where $a$ is the maximal integer such that $y-aD \in H$), and so the second step takes $O(n)$ time.
Without using a hashtable but assuming that the list is sorted, we can solve this in $O(n)$ time as follows:
- Go over all numbers in the list. For each number $x$, add an edge to $x+D$ if $x+D$ is in the list.
- Go over all numbers again. For each number $x$, if there is no edge pointing at $x$, follows the path starting at $x$ and calculate its length.
Using two pointers, we can implement the first step in $O(n)$. (The first pointer points at $x$, the other one is looking for $x+D$.) The second step takes $O(n)$ time for the same reason as in the hashtable algorithm.
Since it takes $O(n\log n)$ time to sort the list, this solution runs in time $O(n\log n)$. Using the fast $O(n\log\log n)$ integer sorting algorithm, we obtain a solution running in time $O(n\log\log n)$.