Easy
题目描述
给定一个 0 索引的整数数组 nums 和一个目标元素 target。
目标索引是使得 nums[i] == target 的索引 i。
返回将 nums 按非递减顺序排序后目标索引的列表。如果没有目标索引,返回空列表。返回的列表必须按递增顺序排序。
示例 1:
输入:nums = [1,2,5,2,3], target = 2
输出:[1,2]
解释:排序后,nums 为 [1,2,2,3,5]。
nums[i] == 2 的索引为 1 和 2。
示例 2:
输入:nums = [1,2,5,2,3], target = 3
输出:[3]
解释:排序后,nums 为 [1,2,2,3,5]。
nums[i] == 3 的索引为 3。
示例 3:
输入:nums = [1,2,5,2,3], target = 5
输出:[4]
解释:排序后,nums 为 [1,2,2,3,5]。
nums[i] == 5 的索引为 4。
约束条件:
1 <= nums.length <= 1001 <= nums[i], target <= 100
提示:
- 试着先"排序"数组。
- 现在找到数组中所有值等于 target 的索引。
解题思路
这道题有两种主要解法,都比较简单直观:
解法一:直接排序法 按照题目提示,先将数组排序,然后遍历找出所有等于 target 的索引。这是最直观的方法,时间复杂度主要由排序决定。
解法二:统计法(优化) 不需要实际排序数组,只需要统计小于 target 的元素个数和等于 target 的元素个数。排序后,target 元素会连续出现,起始位置就是小于 target 的元素个数,结束位置可以通过起始位置加上 target 元素个数计算得出。这种方法时间复杂度更优。
两种解法都能正确解决问题,但统计法在时间复杂度上有优势,特别是当数组较大时。对于本题的约束条件(数组长度最多100),两种方法性能差异不大,但统计法展示了更好的算法思维。
推荐使用统计法,因为它避免了排序操作,时间复杂度更优。
代码实现
class Solution {
public:
vector<int> targetIndices(vector<int>& nums, int target) {
int smaller = 0, equal = 0;
for (int num : nums) {
if (num < target) smaller++;
else if (num == target) equal++;
}
vector<int> result;
for (int i = smaller; i < smaller + equal; i++) {
result.push_back(i);
}
return result;
}
};
class Solution:
def targetIndices(self, nums: List[int], target: int) -> List[int]:
smaller = sum(1 for num in nums if num < target)
equal = sum(1 for num in nums if num == target)
return list(range(smaller, smaller + equal))
public class Solution {
public IList<int> TargetIndices(int[] nums, int target) {
int smaller = 0, equal = 0;
foreach (int num in nums) {
if (num < target) smaller++;
else if (num == target) equal++;
}
var result = new List<int>();
for (int i = smaller; i < smaller + equal; i++) {
result.Add(i);
}
return result;
}
}
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var targetIndices = function(nums, target) {
nums.sort((a, b) => a - b);
const result = [];
for (let i = 0; i < nums.length; i++) {
if (nums[i] === target) {
result.push(i);
}
}
return result;
};
复杂度分析
| 方法 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| 统计法 | O(n) | O(1) |
| 排序法 | O(n log n) | O(1) |
其中 n 为数组长度。统计法只需要遍历一次数组,时间复杂度为 O(n);排序法需要先排序再遍历,时间复杂度为 O(n log n)。两种方法的空间复杂度都是 O(1)(不考虑输出数组)。