Welcome to Subscribe On Youtube
912. Sort an Array
Description
Given an array of integers nums, sort the array in ascending order and return it.
You must solve the problem without using any built-in functions in O(nlog(n)) time complexity and with the smallest space complexity possible.
Example 1:
Input: nums = [5,2,3,1] Output: [1,2,3,5] Explanation: After sorting the array, the positions of some numbers are not changed (for example, 2 and 3), while the positions of other numbers are changed (for example, 1 and 5).
Example 2:
Input: nums = [5,1,1,2,0,0] Output: [0,0,1,1,2,5] Explanation: Note that the values of nums are not necessairly unique.
Constraints:
1 <= nums.length <= 5 * 104-5 * 104 <= nums[i] <= 5 * 104
Solutions
Solution 1: Sliding Window + Sorting
Quick sort is an efficient sorting algorithm. Its basic idea is to divide the data to be sorted into two independent parts through one sorting. All the data in one part is smaller than all the data in the other part. Then the two parts of the data are quickly sorted separately according to this method. The entire sorting process can be performed recursively, so that the entire data becomes an ordered sequence.
Time complexity $O(n \times \log n)$, space complexity $O(\log n)$. Where $n$ is the array length.
Solution 2
Merge sort is a divide-and-conquer algorithm. Its idea is to continuously split the data sequence to be sorted in half until each data block has only one element, and then merge each data block in pairs according to the order of splitting. Sort during the merging process to finally obtain an ordered data sequence.
Merge sort is a stable sorting algorithm with a time complexity of $O(n \times \log n)$ and a space complexity of $O(n)$. Where $n$ is the array length.
Solution 3
This implementation uses sliding window, followed by sorting, followed by bit manipulation. It traverses the relevant values and updates its state as each value is processed. Ordering the data first makes the subsequent comparisons deterministic. After all required states have been considered, the maintained result is returned.
-
class Solution { private int[] nums; public int[] sortArray(int[] nums) { this.nums = nums; quikcSort(0, nums.length - 1); return nums; } private void quikcSort(int l, int r) { if (l >= r) { return; } int x = nums[(l + r) >> 1]; int i = l - 1, j = r + 1; while (i < j) { while (nums[++i] < x) { } while (nums[--j] > x) { } if (i < j) { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; } } quikcSort(l, j); quikcSort(j + 1, r); } } // Solution 2 class Solution { private int[] nums; public int[] sortArray(int[] nums) { this.nums = nums; quickSort(0, nums.length - 1); return nums; } private void quickSort(int l, int r) { if (l >= r) { return; } int i = l - 1, j = r + 1, k = l; int x = nums[(l + r) >> 1]; while (k < j) { if (nums[k] < x) { swap(++i, k++); } else if (nums[k] > x) { swap(--j, k); } else { ++k; } } quickSort(l, i); quickSort(j, r); } private void swap(int i, int j) { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; } } // Solution 3 class Solution { private int[] nums; public int[] sortArray(int[] nums) { this.nums = nums; mergeSort(0, nums.length - 1); return nums; } private void mergeSort(int l, int r) { if (l >= r) { return; } int mid = (l + r) >> 1; mergeSort(l, mid); mergeSort(mid + 1, r); int i = l, j = mid + 1, k = 0; int[] tmp = new int[r - l + 1]; while (i <= mid && j <= r) { if (nums[i] <= nums[j]) { tmp[k++] = nums[i++]; } else { tmp[k++] = nums[j++]; } } while (i <= mid) { tmp[k++] = nums[i++]; } while (j <= r) { tmp[k++] = nums[j++]; } for (i = l; i <= r; ++i) { nums[i] = tmp[i - l]; } } } -
class Solution { public: vector<int> sortArray(vector<int>& nums) { function<void(int, int)> quick_sort = [&](int l, int r) { if (l >= r) { return; } int i = l - 1, j = r + 1; int x = nums[(l + r) >> 1]; while (i < j) { while (nums[++i] < x) { } while (nums[--j] > x) { } if (i < j) { swap(nums[i], nums[j]); } } quick_sort(l, j); quick_sort(j + 1, r); }; quick_sort(0, nums.size() - 1); return nums; } }; // Solution 2 class Solution { public: vector<int> sortArray(vector<int>& nums) { function<void(int, int)> merge_sort = [&](int l, int r) { if (l >= r) { return; } int mid = (l + r) >> 1; merge_sort(l, mid); merge_sort(mid + 1, r); int i = l, j = mid + 1, k = 0; int tmp[r - l + 1]; while (i <= mid && j <= r) { if (nums[i] <= nums[j]) { tmp[k++] = nums[i++]; } else { tmp[k++] = nums[j++]; } } while (i <= mid) { tmp[k++] = nums[i++]; } while (j <= r) { tmp[k++] = nums[j++]; } for (i = l; i <= r; ++i) { nums[i] = tmp[i - l]; } }; merge_sort(0, nums.size() - 1); return nums; } }; -
class Solution: def sortArray(self, nums: List[int]) -> List[int]: def quick_sort(l, r): if l >= r: return x = nums[randint(l, r)] i, j, k = l - 1, r + 1, l while k < j: if nums[k] < x: nums[i + 1], nums[k] = nums[k], nums[i + 1] i, k = i + 1, k + 1 elif nums[k] > x: j -= 1 nums[j], nums[k] = nums[k], nums[j] else: k = k + 1 quick_sort(l, i) quick_sort(j, r) quick_sort(0, len(nums) - 1) return nums # Solution 2 class Solution: def sortArray(self, nums: List[int]) -> List[int]: def merge_sort(l, r): if l >= r: return mid = (l + r) >> 1 merge_sort(l, mid) merge_sort(mid + 1, r) i, j = l, mid + 1 tmp = [] while i <= mid and j <= r: if nums[i] <= nums[j]: tmp.append(nums[i]) i += 1 else: tmp.append(nums[j]) j += 1 if i <= mid: tmp.extend(nums[i : mid + 1]) if j <= r: tmp.extend(nums[j : r + 1]) for i in range(l, r + 1): nums[i] = tmp[i - l] merge_sort(0, len(nums) - 1) return nums -
func sortArray(nums []int) []int { quickSort(nums, 0, len(nums)-1) return nums } func quickSort(nums []int, l, r int) { if l >= r { return } i, j := l-1, r+1 x := nums[(l+r)>>1] for i < j { for { i++ if nums[i] >= x { break } } for { j-- if nums[j] <= x { break } } if i < j { nums[i], nums[j] = nums[j], nums[i] } } quickSort(nums, l, j) quickSort(nums, j+1, r) } // Solution 2 func sortArray(nums []int) []int { mergeSort(nums, 0, len(nums)-1) return nums } func mergeSort(nums []int, l, r int) { if l >= r { return } mid := (l + r) >> 1 mergeSort(nums, l, mid) mergeSort(nums, mid+1, r) i, j, k := l, mid+1, 0 tmp := make([]int, r-l+1) for i <= mid && j <= r { if nums[i] <= nums[j] { tmp[k] = nums[i] i++ } else { tmp[k] = nums[j] j++ } k++ } for ; i <= mid; i++ { tmp[k] = nums[i] k++ } for ; j <= r; j++ { tmp[k] = nums[j] k++ } for i = l; i <= r; i++ { nums[i] = tmp[i-l] } } -
function sortArray(nums: number[]): number[] { function quickSort(l: number, r: number) { if (l >= r) { return; } let i = l - 1; let j = r + 1; const x = nums[(l + r) >> 1]; while (i < j) { while (nums[++i] < x); while (nums[--j] > x); if (i < j) { [nums[i], nums[j]] = [nums[j], nums[i]]; } } quickSort(l, j); quickSort(j + 1, r); } const n = nums.length; quickSort(0, n - 1); return nums; } // Solution 2 function sortArray(nums: number[]): number[] { function mergetSort(l: number, r: number) { if (l >= r) { return; } const mid = (l + r) >> 1; mergetSort(l, mid); mergetSort(mid + 1, r); let [i, j, k] = [l, mid + 1, 0]; while (i <= mid && j <= r) { if (nums[i] <= nums[j]) { tmp[k++] = nums[i++]; } else { tmp[k++] = nums[j++]; } } while (i <= mid) { tmp[k++] = nums[i++]; } while (j <= r) { tmp[k++] = nums[j++]; } for (i = l, j = 0; i <= r; ++i, ++j) { nums[i] = tmp[j]; } } const n = nums.length; let tmp = new Array(n).fill(0); mergetSort(0, n - 1); return nums; } -
/** * @param {number[]} nums * @return {number[]} */ var sortArray = function (nums) { function quickSort(l, r) { if (l >= r) { return; } let i = l - 1; let j = r + 1; const x = nums[(l + r) >> 1]; while (i < j) { while (nums[++i] < x); while (nums[--j] > x); if (i < j) { [nums[i], nums[j]] = [nums[j], nums[i]]; } } quickSort(l, j); quickSort(j + 1, r); } const n = nums.length; quickSort(0, n - 1); return nums; }; // Solution 2 /** * @param {number[]} nums * @return {number[]} */ var sortArray = function (nums) { function mergetSort(l, r) { if (l >= r) { return; } const mid = (l + r) >> 1; mergetSort(l, mid); mergetSort(mid + 1, r); let [i, j, k] = [l, mid + 1, 0]; while (i <= mid && j <= r) { if (nums[i] <= nums[j]) { tmp[k++] = nums[i++]; } else { tmp[k++] = nums[j++]; } } while (i <= mid) { tmp[k++] = nums[i++]; } while (j <= r) { tmp[k++] = nums[j++]; } for (i = l, j = 0; i <= r; ++i, ++j) { nums[i] = tmp[j]; } } const n = nums.length; let tmp = new Array(n).fill(0); mergetSort(0, n - 1); return nums; }; -
impl Solution { pub fn sort_array(mut nums: Vec<i32>) -> Vec<i32> { let n = nums.len(); Self::quick_sort(&mut nums, 0, n - 1); return nums; } fn quick_sort(nums: &mut Vec<i32>, left: usize, right: usize) { if left >= right { return; } let mut i = left as i32 - 1; let mut j = right as i32 + 1; let pivot = nums[left]; while i < j { loop { i += 1; if nums[i as usize] >= pivot { break; } } loop { j -= 1; if nums[j as usize] <= pivot { break; } } if i < j { nums.swap(i as usize, j as usize); } } Self::quick_sort(nums, left, j as usize); Self::quick_sort(nums, j as usize + 1, right); } } -
class Solution { fun sortArray(nums: IntArray): IntArray { fun quickSort(left: Int, right: Int) { if (left >= right) { return } var i = left - 1 var j = right + 1 val pivot = nums[left] while (i < j) { while (nums[++i] < pivot) ; while (nums[--j] > pivot) ; if (i < j) { val temp = nums[i] nums[i] = nums[j] nums[j] = temp } } quickSort(left, j) quickSort(j + 1, right) } quickSort(0, nums.size - 1) return nums } }