我正在工作leetcode问题编号1365。这是下面用斜体字符显示的问题:
给出数组nums,对于每个nums [i]找出数组中比其小的数字。也就是说,对于每个nums [i],您都必须计算有效j的数量,以使j!= i,并且nums [j]
https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/
我能够使用蛮力完成O(n ^ 2)时间的任务。有没有更快的方法来编码此问题?
code_lowered
答案 0 :(得分:2)
一个简单的O(nlgn)
空间为O(n)
的解决方案是:
O(n)
O(ngln)
答案 1 :(得分:1)
有一种更好的O(n^2)
方法,您只比较每对索引一次并相应地更新计数:
public static int[] smallerNumbersThanCurrent(int[] nums)
{
int[] result = new int[nums.length];
for (int x = 0; x < nums.length; x++)
{
for (int y = x + 1; y < nums.length; y++)
{
if (nums[y] < nums[x])
result[x]++;
else if (nums[y] > nums[x])
result[y]++;
}
}
return result;
}
但是,我们可以在O(ngln)
中进行操作,方法是对原始数组的索引进行排序,然后遍历这些排序的索引,从而相应地更新计数,这需要付出额外的数组代价。唯一的麻烦在于处理重复的数字,例如您示例中的2s。
public static int[] smallerNumbersThanCurrent(int[] nums)
{
Integer[] idx = new Integer[nums.length];
for(int i=0; i<idx.length; i++) idx[i] = i;
Arrays.sort(idx, (a, b) -> (nums[a]-nums[b]));
int[] res = new int[nums.length];
for(int i=1; i<idx.length; i++)
{
if(nums[idx[i]] == nums[idx[i-1]])
res[idx[i]] = res[idx[i-1]];
else
res[idx[i]] = i;
}
return res;
}
测试:
int[] nums = new int[] {8,1,2,2,3};
System.out.println(Arrays.toString(smallerNumbersThanCurrent(nums)));
输出:
[4, 0, 1, 1, 3]