Easy
题目描述
给你一个整数数组 nums,它表示一个循环数组。你的任务是创建一个相同大小的新数组 result,遵循以下规则:
对于每个索引 i(其中 0 <= i < nums.length),执行以下独立操作:
- 如果
nums[i] > 0:从索引i开始,在循环数组中向右移动nums[i]步。将result[i]设置为你到达的索引处的值。 - 如果
nums[i] < 0:从索引i开始,在循环数组中向左移动abs(nums[i])步。将result[i]设置为你到达的索引处的值。 - 如果
nums[i] == 0:将result[i]设置为nums[i]。
返回新数组 result。
注意:由于 nums 是循环的,移动超过最后一个元素会回绕到开头,移动超过第一个元素会回绕到结尾。
示例 1:
输入:nums = [3,-2,1,1]
输出:[1,1,1,3]
解释:
- 对于 nums[0] = 3,向右移动 3 步,到达 nums[3],所以 result[0] = 1
- 对于 nums[1] = -2,向左移动 2 步,到达 nums[3],所以 result[1] = 1
- 对于 nums[2] = 1,向右移动 1 步,到达 nums[3],所以 result[2] = 1
- 对于 nums[3] = 1,向右移动 1 步,到达 nums[0],所以 result[3] = 3
示例 2:
输入:nums = [-1,4,-1]
输出:[-1,-1,4]
解释:
- 对于 nums[0] = -1,向左移动 1 步,到达 nums[2],所以 result[0] = -1
- 对于 nums[1] = 4,向右移动 4 步,到达 nums[2],所以 result[1] = -1
- 对于 nums[2] = -1,向左移动 1 步,到达 nums[1],所以 result[2] = 4
约束:
1 <= nums.length <= 100-100 <= nums[i] <= 100
解题思路
这道题是一个典型的数组模拟题,关键在于理解循环数组的移动规则。
思路分析:
对于循环数组,当我们从索引 i 开始移动 k 步时,需要处理越界情况:
- 向右移动:新索引 =
(i + k) % n - 向左移动:新索引 =
(i - k + n) % n或者(i - k % n + n) % n
具体步骤:
- 遍历原数组的每个位置
i - 根据
nums[i]的值判断移动方向和步数 - 计算目标索引,处理循环数组的边界情况
- 将目标位置的值赋给
result[i]
注意事项:
- 当
nums[i] == 0时,直接将nums[i]赋给result[i] - 负数移动时,为避免负数取模的问题,可以先加上数组长度的倍数确保结果为正
- 由于数组长度最大为100,元素值最大为±100,不会出现整数溢出
时间复杂度为 O(n),空间复杂度为 O(1)(不计算结果数组)。
代码实现
class Solution {
public:
vector<int> constructTransformedArray(vector<int>& nums) {
int n = nums.size();
vector<int> result(n);
for (int i = 0; i < n; i++) {
if (nums[i] == 0) {
result[i] = nums[i];
} else if (nums[i] > 0) {
int newIndex = (i + nums[i]) % n;
result[i] = nums[newIndex];
} else {
int newIndex = (i + nums[i] % n + n) % n;
result[i] = nums[newIndex];
}
}
return result;
}
};
class Solution:
def constructTransformedArray(self, nums: List[int]) -> List[int]:
n = len(nums)
result = [0] * n
for i in range(n):
if nums[i] == 0:
result[i] = nums[i]
elif nums[i] > 0:
new_index = (i + nums[i]) % n
result[i] = nums[new_index]
else:
new_index = (i + nums[i] % n + n) % n
result[i] = nums[new_index]
return result
public class Solution {
public int[] ConstructTransformedArray(int[] nums) {
int n = nums.Length;
int[] result = new int[n];
for (int i = 0; i < n; i++) {
if (nums[i] == 0) {
result[i] = nums[i];
} else if (nums[i] > 0) {
int newIndex = (i + nums[i]) % n;
result[i] = nums[newIndex];
} else {
int newIndex = (i + nums[i] % n + n) % n;
result[i] = nums[newIndex];
}
}
return result;
}
}
var constructTransformedArray = function(nums) {
const n = nums.length;
const result = new Array(n);
for (let i = 0; i < n; i++) {
if (nums[i]
复杂度分析
| 复杂度 | 大小 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(1) |
其中 n 是数组的长度。时间复杂度为 O(n) 因为我们需要遍历数组一次。空间复杂度为 O(1),不计算结果数组的存储空间。