LeetCode 1365 有多少小於當前數字的數
阿新 • • 發佈:2020-10-28
LeetCode 1365 有多少小於當前數字的數
https://leetcode-cn.com/problems/how-many-numbers-are-smaller-than-the-current-number/
暴力列舉
因為資料量並不大,即使是複雜度高的暴力列舉也應該能通過。所以先把暴力列舉法安排上。
class Solution { public: // time and space complexity : O(N^2), O(1) vector<int> smallerNumbersThanCurrent(vector<int>& nums) { int sz = nums.size(); vector<int> ans(sz, 0); for (int i = 0; i < sz; ++i) { int cnt = 0; for (int j = 0; j < sz; ++j) { if (nums[j] < nums[i]) ++cnt; } ans[i] = cnt; } return ans; } };
快速排序
如果我們把陣列排序,那麼對於排序後陣列的某一個數而言,它前面有多少個數就說明有多少個數小於它。而該數前面有多少個數又反應在它的下標之中。但是,這裡需要注意兩個問題:
(1)排序後原陣列的順序就變了,所以需要原陣列中的下標;
(2)如果陣列中有相同元素,那麼它們在排序之後會排在一起,它們的下標彼此不同但是陣列中小於它的數數量卻是相同的,這種情況需要做特殊處理。
struct MyCompare { bool operator()(const pair<int, int>& a, const pair<int, int>& b) { return a.first < b.first; } } cmp; class Solution { public: // time and space complexity : O(NlogN), O(N) vector<int> smallerNumbersThanCurrent(vector<int>& nums) { int sz = nums.size(); vector<pair<int, int>> arr; for (int i = 0; i < sz; ++i) { arr.push_back(make_pair(nums[i], i)); } vector<int> ans(sz, 0); sort(arr.begin(), arr.end(), cmp); int prev = -1; for (int i = 0; i < sz; ++i) { int idx = arr[i].second; if (prev == -1 || arr[i].first != arr[i - 1].first) { prev = i; } // 如果arr[i]和arr[i - 1]是相同的,則prev的值仍維持不變 ans[idx] = prev; } return ans; } };
計數排序
既然快速排序能夠達到解題的目的,那麼其他的排序方式同樣也可以。注意到題目限定陣列中每個元素的範圍在0和100之間,這個範圍不大,這提示我們可以使用計數排序。和上面的快排方法類似,只不過排序方法變成了計數排序。程式碼略。