That's very neat. I'm not sure why it'd be a problem with overflow though. Just add the numbers mod m, where m is greater than the largest number, e.g. 2^32. For the first do sum(array) - sum(1..n-1), for the second do sum(1..n+1) - sum(array). Since e.g. the integers modulu n under addition is an abelian group, cancellation works as expected.

A less elegant, but completely different way that I thought of first would be to "attempt" a sort of count-sort of the numbers. When doing this for the first problem, at some point you're going to find the duplicate element. In Python (for 0..n-1):

def find_extra(a):
   for i in range(len(a)):
      while a[i] != i:
         j = a[i]
         a[i], a[j] = a[j], a[i] # swap
         if a[i] < i:
            return a[i]

The second problem could be sledge-hammered into a similar solution:

def find_missing(a):
   lastp = len(a)
   for i in range(len(a)):
      while a[i] != i:
         j = a[i]
         if a[i] == len(a):
            lastp = i
            break
         a[i], a[j] = a[j], a[i] # swap
   return lastp