前往
大廳
主題

LeetCode - 1920. Build Array from Permutation 解題心得

Not In My Back Yard | 2021-10-30 00:00:03 | 巴幣 0 | 人氣 1156

題目連結:


題目意譯:
給定一個 0-基準排列 nums(索引值從 0 開始),建立一個相同長度的陣列 ans,其中 ans[i] = nums[nums[i]] 對於 0 ≦ i < nums.length 並回傳它。

一個 0-基準排列 nums 為一個由相異整數 0(含)到 nums.length - 1(含)組成的陣列。

限制:
1 ≦ nums.length ≦ 1000
0 ≦ nums[i] < nums.length
nums 中的元素皆相異。

進階: 你可以在不使用額外空間(即 O(1) 空間)的情況下解出來嗎?



範例測資:
範例 1:
輸入: nums = [0,2,1,5,3,4]
輸出: [0,1,2,4,5,3]
解釋: 陣列 ans 可以由如下方式建立:
ans = [nums[nums[0]], nums[nums[1]], nums[nums[2]], nums[nums[3]], nums[nums[4]], nums[nums[5]]]
    = [nums[0], nums[2], nums[1], nums[5], nums[3], nums[4]]
    = [0,1,2,4,5,3]

範例 2:
輸入: nums = [5,0,1,2,3,4]
輸出: [4,5,0,1,2,3]
解釋: 陣列 ans 可以由如下方式建立:
ans = [nums[nums[0]], nums[nums[1]], nums[nums[2]], nums[nums[3]], nums[nums[4]], nums[nums[5]]]
    = [nums[5], nums[0], nums[1], nums[2], nums[3], nums[4]]
    = [4,5,0,1,2,3]


解題思維:
雖然可以直接建立另一個陣列然後按照題目所求為每個位置依序放入 nums[nums[0]] 、 nums[nums[1]] 、……

不過我們可以原地(In-Place)地將原陣列直接更動成題目所求的樣子(假設陣列長度為 n):
如果我們直接地按照題目所求去更動原陣列,我們基本上會立刻遭遇位置 i 的目標數字 nums[nums[i]] 已經被更動的情況(這樣便不符合題目所求)。那我們有辦法可以「間接地」更動嗎?

答案是可以的,只要利用餘數的特性—— a + b × n ≡ a (mod n)

因為陣列中的數字介於 0 ~ n - 1 中,而這正好可以套入 a 、 b 的位置。因此我們在更動位置 i 時,我們可以將 nums[i] 加上 nums[nums[i]] 乘以 n 後的值。因此此時該位置的值便變成了 nums[i] + nums[nums[i]] × n,當模 n 時我們便可以求得原本位置 i 的數字 nums[i]、而除以 n 取整數便可以得到所求的 nums[nums[i]]。

因此按照以上特性並套用到每個位置的值。最後再掃過一次對每個數字除以 n 並取整便可以得到所求陣列。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作