text: #!/usr/bin/env python3
  # -*- coding: utf-8 -*-
  """
  Created on Wed Jan 20 15:42:19 2021
  
  @author: dopiwoo
  
  We are given an unsorted array containing numbers taken from the range 1 to 'n'. The array can have duplicates, which
  means some numbers will be missing. Find all those missing numbers.
  
  Example 1:
  Input: [2, 3, 1, 8, 2, 3, 5, 1]
  Output: 4, 6, 7
  Explanation: The array should have all numbers from 1 to 8, due to duplicates 4, 6, and 7 are missing.
  
  Example 2:
  Input: [2, 4, 1, 2]
  Output: 3
  
  Example 2:
  Input: [2, 3, 2, 1]
  Output: 4
  """
  
  from typing import List
  
  
  def find_missing_numbers(nums: List[int]) -> List[int]:
      """
      Time Complexity: O(N)
      Space Complexity: O(1)
  
      Parameters
      ----------
      nums : List[int]
          Input array containing numbers taken from the range 1 to 'n'.
  
      Returns
      -------
      res : List[int]
          All missing numbers in the array.
  
      """
      i = 0
      res = []
      while i < len(nums):
          j = nums[i] - 1
          if nums[i] != nums[j]:
              nums[i], nums[j] = nums[j], nums[i]
          else:
              i += 1
      for i in range(len(nums)):
          if nums[i] != i + 1:
              res.append(i + 1)
      return res
  
  
  if __name__ == '__main__':
      print(find_missing_numbers([2, 3, 1, 8, 2, 3, 5, 1]))
      print(find_missing_numbers([2, 4, 1, 2]))
      print(find_missing_numbers([2, 3, 2, 1]))
  