3379. 轉換數組

簡單 數組 模擬

思路

按照題目要求模擬就好。

  • nums[i]>0nums[i] > 0 ,找到右邊 nums[i]nums[i] 的數字,放到 res[i]res[i] 上。
  • nums[i]<0nums[i] < 0 ,找到左邊 nums[i]nums[i] 的數字,放到 res[i]res[i] 上。
  • nums[i]=0nums[i] = 0 ,找到當前 nums[i]nums[i] 的數字,放到 res[i]res[i] 上。

這三種情況是一樣的,根據 nums[i]nums[i] 的數字大小,決定找的方向以及距離。
先不考慮負數,如果是往右 xx 位,當這個數字 xx 很大的時候,要怎麼快速找到目標位置?

注意到如果 xxnn 的倍數的話,會回到原先的位置,因此可以透過模 nn 的方式,快速找到目標位置。

對於負數的情況,我們知道想要得到正確的模運算結果應該,要先加上 nn ,比如 n=7n = 7 時。
(7517)%7=2(75-17)\%7=2(75%717%7+7)%7=(53+7)%7=2(75\%7-17\%7\blue{+7})\%7=(5-3\blue{+7})\%7 = 2 ,需要再模運算之後,再加上一個 nn
上面的例子看起來 +n+n 很廢,這也是特性之一,也就是最後算出正數,那加與不加都沒差。
(7218)%7=54%7=5(72-18)\%7=54\%7=5(72%718%7+7)%m=(24+7)%7=5(72\%7-18\%7+7)\%m=(2-4+7)\%7=5
第二個例子中,相減之後是負數,但是餘數不會有負數,因此要加 77 取補數。

之所以 +n+n 是為了取補數,不過前提是模的數字絕對值不可以大於 nn
否則取到的補數會出錯。因此要事先對數值 %n\%n

程式碼

1. 模擬

class Solution {
public:
    vector<int> constructTransformedArray(vector<int>& nums) {
        int n = nums.size();
        vector<int> res(n);
        for(int i = 0; i < n; i++) {
            int j;
            if(nums[i] < 0) {
                // 減太多會有很多輪,還會爆炸,要事先 % n
                j = (i + -(abs(nums[i]) % n) + n) % n;
            }
            else {
                j = (i + nums[i]) % n;
            }
            res[i] = nums[j];
        }
        return res;
    }
};

2. 合併正負兩種狀況

class Solution {
public:
    vector<int> constructTransformedArray(vector<int>& nums) {
        int n = nums.size();
        vector<int> res(n);
        for(int i = 0; i < n; i++) {
            int j = ((i + nums[i]) % n + n) % n;
            res[i] = nums[j];
        }
        return res;
    }
};

複雜度分析

  • 時間複雜度:O(n)O(n)
  • 空間複雜度:O(n)O(n)

顯示設定

背景線條
顯示背景網格線條
懸停發光
滑鼠懸停時顯示霓虹效果
聚光燈
跟隨滑鼠的聚光燈效果
背景透明度
開啟透明玻璃效果
主題顏色
自訂主要顏色