From d4f6d7e664649259b5db14772d9eaf3b9998403b Mon Sep 17 00:00:00 2001 From: begeekmyfriend Date: Sat, 28 Oct 2023 09:27:16 +0800 Subject: [PATCH] Improvement Signed-off-by: begeekmyfriend --- .../rotated_array.c | 2 + .../rotated_array.cc | 5 ++ .../kth_elem.c | 55 ++++++++++--------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/0033_search_in_rotated_sorted_array/rotated_array.c b/0033_search_in_rotated_sorted_array/rotated_array.c index 822c2ee..07d508c 100644 --- a/0033_search_in_rotated_sorted_array/rotated_array.c +++ b/0033_search_in_rotated_sorted_array/rotated_array.c @@ -12,6 +12,8 @@ static int search(int* nums, int numsSize, int target) return mid; } + /* lo might be mid */ + /* We only need to consider non-rotated sorted array search */ if (nums[lo] <= nums[mid]) { if (nums[lo] <= target && target < nums[mid]) { hi = mid - 1; diff --git a/0033_search_in_rotated_sorted_array/rotated_array.cc b/0033_search_in_rotated_sorted_array/rotated_array.cc index 6332d10..67d0ec8 100644 --- a/0033_search_in_rotated_sorted_array/rotated_array.cc +++ b/0033_search_in_rotated_sorted_array/rotated_array.cc @@ -7,11 +7,15 @@ class Solution { int search(vector& nums, int target) { int lo = 0; int hi = nums.size() - 1; + for (lo <= hi) { int mid = lo + (hi - lo) / 2; if (nums[mid] == target) { return mid; } + + // lo might be mid + // We only need to consider non-rotated sorted array search if (nums[lo] <= nums[mid]) { if (nums[lo] <= target && target < nums[mid]) { hi = mid - 1; @@ -26,6 +30,7 @@ class Solution { } } } + return -1; } }; diff --git a/0215_kth_largest_element_in_an_array/kth_elem.c b/0215_kth_largest_element_in_an_array/kth_elem.c index c4f6294..4551749 100644 --- a/0215_kth_largest_element_in_an_array/kth_elem.c +++ b/0215_kth_largest_element_in_an_array/kth_elem.c @@ -1,44 +1,47 @@ #include #include +static inline void swap(int *a, int *b) +{ + int t = *a; + *a = *b; + *b = t; +} -static int partition(int *nums, int lo, int hi) +static int quick_select(int *nums, int lo, int hi, int k) { if (lo >= hi) { return hi; } - int i = lo; - int j = hi; - int pivot = nums[hi]; + int i = lo - 1; + int j = hi + 1; + int pivot = nums[lo]; while (i < j) { - while (i < j && nums[i] <= pivot) { i++; } - /* Loop invariant: nums[i] > pivot or i == j */ - nums[j] = nums[i]; - while (i < j && nums[j] >= pivot) { j--; } - /* Loop invariant: nums[j] > pivot or i == j */ - nums[i] = nums[j]; + /* For case of large amounts of consecutive duplicate elements, we + * shall make the partition in the middle of the array as far as + * possible. If the partition is located in the head or tail, the + * performance might well be very bad for it. + */ + while (nums[++i] > pivot) {} + while (nums[--j] < pivot) {} + if (i < j) { + swap(&nums[i], &nums[j]); + } + } + + /* invariant: i == j + 1 or i == j */ + if (j >= k - 1) { + return quick_select(nums, lo, j, k); + } else { + return quick_select(nums, j + 1, hi, k); } - /* Loop invariant: i == j */ - nums[i] = pivot; - return i; } int findKthLargest(int* nums, int numsSize, int k) { - int lo = 0, hi = numsSize - 1; - for (; ;) { - int p = partition(nums, lo, hi); - if (p < numsSize - k) { - lo = p + 1; - } else if (p > numsSize - k) { - hi = p - 1; - } else { - lo = p; - break; - } - } - return nums[lo]; + int i = quick_select(nums, 0, numsSize - 1, k); + return nums[i]; }