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

具体步骤:

  1. 遍历原数组的每个位置 i
  2. 根据 nums[i] 的值判断移动方向和步数
  3. 计算目标索引,处理循环数组的边界情况
  4. 将目标位置的值赋给 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),不计算结果数组的存储空间。