Leetcode 315.计算右侧小于当前元素的个数
1.题目链接
https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/
2.题目描述
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
示例:
输入: [5,2,6,1] 输出: [2,1,1,0] 解释: 5 的右侧有 2 个更小的元素 (2 和 1). 2 的右侧仅有 1 个更小的元素 (1). 6 的右侧有 1 个更小的元素 (1). 1 的右侧有 0 个更小的元素.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
3.解题思路
3.1暴力解法
首先想到的是用双重循环实现,直接比较nums[i]后面比自身小的个数即可,不过在执行代码时,超出时间限制。
3.1.1代码实现
int* countSmaller(int* nums, int numsSize, int* returnSize){ int *res = (int *)malloc(numsSize * sizeof(int)); memset(res, 0, numsSize * sizeof(int)); for (int i = 0; i < numsSize; i++) { for (int j = i + 1; j < numsSize; j++) { if (nums[i] > nums[j] ) res[i]++; } } *returnSize = numsSize; return res; }
3.1.2提交记录
3.2 二分查找+插入排序
用二分法查找,找到第一个小于val值的元素,再用插入排序的方法,保证后面的元素都是有序的。
3.2.1 代码实现
/** * Note: The returned array must be malloced, assume caller calls free(). */ int binarysearch(int nums[], int start, int end, int val) { int left = start; int right = end - 1; int mid; while (left <= right) { mid = (left + right) / 2; if (nums[mid] < val) left = mid + 1; else right = mid - 1; } return left; } void insert(int *nums, int start, int end, int val, int index) { for (int i = end; i >= start; i--) { if (i == index) { nums[i] = val; break; } else if (i != 0) { nums[i] = nums[i - 1]; } } } int* countSmaller(int* nums, int numsSize, int* returnSize){ int *res = (int *)malloc(numsSize * sizeof(int)); int *count = (int *)malloc(numsSize * sizeof(int)); memset(res, 0, numsSize * sizeof(int)); memset(count, 0, numsSize * sizeof(int)); int cnt = 0; for (int i = numsSize - 1; i >= 0; i--) { int index = binarysearch(res, 0, cnt, nums[i]); count[i] = index; insert(res, 0, cnt, nums[i], index); cnt++; } *returnSize = numsSize; free(res); return count; }
3.2.2提交记录
stay hungry, stay foolish