Given an integer array of even length arr, return true if it is possible to reorder arr such that arr[2 * i + 1] = 2 * arr[2 * i] for every 0 <= i < len(arr) / 2, or false otherwise.
給予一個長度為偶數的整數陣列 arr,如果可以重新排序 arr 使得每個 0 <= i < len(arr) / 2 且 arr[2 * i + 1] = 2 * arr[2 * i], 則回傳 true,否則回傳 false。
Example 1:
Input: arr = [3,1,3,6] Output: false
Example 2:
Input: arr = [2,1,2,6] Output: false
Example 3:
Input: arr = [4,-2,2,-4] Output: true Explanation: We can take two groups, [-2,-4] and [2,4] to form [-2,-4,2,4] or [2,4,-2,-4].
Solution:
從題意我們可以知道我們可以重新排列陣列裡元素的順序,
同時我們需要兩兩配對,確保而後一個恰好是前一個的兩倍 arr[2 * i + 1] = 2 * arr[2 * i]。
這個過程我們需要注意幾個重點:
1. 陣列元素內使用的次數,不能重複,因為需要配對。(ex. HashTable 來計算次數)
2. 接著我們要比較的是倍數,所以在不論正負數的情況下,我們按照絕對值下去從小到大排序,確保小的先配對。
3. 配對成功的兩個元素皆需要扣除,遍歷配對的元素就不需要配對。
4. 如果無法配對或要配對數值的兩倍已無次數,則回傳 false,否則回傳 true。
Code 1: BigO(n log n)
function canReorderDoubled(arr: number[]): boolean { let hashTable: Record= {} for (let num of arr) { hashTable[num] = (hashTable[num] || 0) + 1; } arr.sort((a, b) => Math.abs(a) - Math.abs(b)) for (let num of arr) { if (hashTable[num] === 0) continue; const doubledNum = num * 2; if (!hashTable[doubledNum] || hashTable[doubledNum] <= 0) { return false; } hashTable[num]--; hashTable[doubledNum]--; } return true; };
FlowChart:
Example 1
Input: arr = [3,1,3,6] hashTable { '1': 1, '3': 2, '6': 1 } arr [ 1, 3, 3, 6 ] num 1, doubledNum 2, !hashTable[doubledNum] true, hashTable[doubledNum] <= 0 false // return false; 找不到當前元素的兩倍值
Example 2
Input: arr = [2,1,2,6] hashTable { '1': 1, '2': 2, '6': 1 } arr [ 1, 2, 2, 6 ] num 1, doubledNum 2, !hashTable[doubledNum] false, hashTable[doubledNum] <= 0 false num 2, doubledNum 4, !hashTable[doubledNum] true, hashTable[doubledNum] <= 0 false // return false; 找不到當前元素的兩倍值
Example 3
Input: arr = [4,-2,2,-4] hashTable { '2': 1, '4': 1, '-2': 1, '-4': 1 } arr [ -2, 2, 4, -4 ] num -2, doubledNum -4, !hashTable[doubledNum] false, hashTable[doubledNum] <= 0 false num 2, doubledNum 4, !hashTable[doubledNum] false, hashTable[doubledNum] <= 0 false num 4 // 已被配對 num -4 // 已被配對 return true; // 回圈順利走完,結束。