一、Problem
Given the array nums, for each nums[i] find out how many numbers in the array are smaller than it. That is, for each nums[i] you have to count the number of valid j’s such that j != i and nums[j] < nums[i].
Return the answer in an array.
Input: nums = [8,1,2,2,3]
Output: [4,0,1,1,3]
Explanation:
For nums[0]=8 there exist four smaller numbers than it (1, 2, 2 and 3).
For nums[1]=1 does not exist any smaller number than it.
For nums[2]=2 there exist one smaller number than it (1).
For nums[3]=2 there exist one smaller number than it (1).
For nums[4]=3 there exist three smaller numbers than it (1, 2 and 2).
二、Solution
方法一:排序
- Brute force 不難想,但也卻是存在更優解。
- 比如說當 nums 是有序的情況下,那麼最後一個元素 b 肯定是最大的,那麼 b 的前面的所有元素都比 b 小。
class Solution {
public int[] smallerNumbersThanCurrent(int[] nums) {
int N = nums.length, a[] = new int[N];
a = Arrays.copyOf(nums, N);
Arrays.sort(a);
Map<Integer, Integer> mp = new HashMap<>();
for (int i = 0; i < N; i++)
mp.putIfAbsent(a[i], i);
for (int i = 0; i < N; i++)
nums[i] = mp.get(nums[i]);
return nums;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:桶排序
- 最簡單的桶排序就是用一個整形數組
int[] freq
對元素進行計數,然後如果某個元素 a 出現頻次爲 n 次,則將 a 輸出 n 次 - 在這提應用起來就是:某個桶
freq[i]
前面所有元素的頻次就是有多少元素小於當前元素。
class Solution {
public int[] smallerNumbersThanCurrent(int[] nums) {
int N = nums.length, freq[] = new int[100+5];
for (int n : nums) freq[n]++;
for (int i = 1; i < freq.length; i++) freq[i] += freq[i-1];
int[] res = new int[N];
for (int i = 0; i < N; i++) {
if (nums[i] > 0)
res[i] = freq[nums[i]-1];
}
return res;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,