Common algorithms that are useful for code competition.
Iterate the whole list, every time compare every element in the new list to decide where to insert the current element.
Time complexity: o ( n 2 ) o(n^2) o(n2)
Space complexity: o ( n ) o(n) o(n)
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
sorted_nums = []
for each_num in nums:
i = 0
while i < len(sorted_nums):
if sorted_nums[i] < each_num:
i += 1
else:
break
sorted_nums.insert(i, each_num)
return sorted_nums
Every time sort one element to the final position.
Time complexity: o ( n 2 ) o(n^2) o(n2)
Space complexity: o ( 1 ) o(1) o(1)
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
for i in range(len(nums) - 1, -1, -1):
for j in range(1, i + 1):
if nums[j - 1] > nums[j]:
nums[j - 1], nums[j] = nums[j], nums[j - 1]
return nums
Every time select the minimum/maximum element, and put it to the final position.
Time complexity: o ( n 2 ) o(n^2) o(n2)
Space complexity: o ( 1 ) o(1) o(1)
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
for i in range(len(nums)):
cur_min, cur_min_index = 50001, -1
for j in range(i, len(nums)):
if nums[j] < cur_min:
cur_min = nums[j]
cur_min_index = j
nums[i], nums[cur_min_index] = nums[cur_min_index], nums[i]
return nums
Every time, put all the smaller numbers in the left, put all the larger numbers in the right.
Time complexity: o ( n log n ) o(n \log n) o(nlogn), in worst case it would be o ( n 2 ) o(n^2) o(n2), where pivot
is always the largest/smallest element.
Space complexity: o ( n ) o(n) o(n), key point: skip pivot when adding elements into smaller
and larger
.
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
if len(nums) < 2:
return nums
pivot = random.choice(nums)
smaller_nums = [item for item in nums if item < pivot]
larger_nums = [item for item in nums if item > pivot]
equals = [item for item in nums if item == pivot]
return self.sortArray(smaller_nums) + equals + self.sortArray(larger_nums)
Space complexity: o ( 1 ) o(1) o(1)
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
def helper(left: int, right: int) -> None:
if left >= right:
return
pivot = nums[random.randint(left, right)]
small_index, large_index = left, right
p = left
while p <= large_index:
if nums[p] < pivot:
nums[small_index], nums[p] = nums[p], nums[small_index]
small_index += 1
p += 1
elif nums[p] > pivot:
nums[large_index], nums[p] = nums[p], nums[large_index]
large_index -= 1
else:
p += 1
helper(left, small_index - 1)
helper(large_index + 1, right)
helper(0, len(nums) - 1)
return nums
Merge sort the left half and the right half, then merge two sorted lists.
Time complexity: o ( n log n ) o(n \log n) o(nlogn)
Space complexity: o ( n ) o(n) o(n)
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
def merge_sorted_list(nums1: list, nums2: list) -> list:
p1, p2 = 0, 0
res = []
while p1 < len(nums1) or p2 < len(nums2):
if p1 < len(nums1) and p2 < len(nums2):
if nums1[p1] <= nums2[p2]:
res.append(nums1[p1])
p1 += 1
else:
res.append(nums2[p2])
p2 += 1
elif p1 < len(nums1):
res += nums1[p1:]
break
elif p2 < len(nums2):
res += nums2[p2:]
break
return res
if len(nums) == 1:
return nums
sorted1, sorted2 = self.sortArray(nums[:len(nums) // 2]), self.sortArray(nums[len(nums) // 2:])
return merge_sorted_list(sorted1, sorted2)
Use a count
auxiliary list to store the count of each element, and then transform it into a pre sum list, to denote how many numbers that are smaller than the current number there are, and use this number to decide the final position of each element.
Time complexity: o ( n + k ) o(n+k) o(n+k), where n
is the number of elements, and k
is the maximum element.
Space complexity: o ( n + k ) o(n+k) o(n+k)
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
# k: [-5*10^4, 5*10^4]
count_list = [0] * 100001
offset = 50000
for each_num in nums:
count_list[each_num + offset] += 1
for i in range(1, len(count_list)):
count_list[i] += count_list[i - 1]
res = [0] * len(nums)
for each_num in nums:
position = count_list[each_num + offset] - 1
res[position] = each_num
count_list[each_num + offset] -= 1
return res