【死磕演算法之1刷leetcode】954. Array of Doubled Pairs
題目是周賽的第二題,難度中等。
題目描述:
Given an array of integers A with even length, return true if and only if it is possible to reorder it such that A[2 * i + 1] = 2 * A[2 * i] for every 0 <= i < len(A) / 2.
舉例:
Example 1:
Input: [3,1,3,6]
Output: false
Example 2:
Input: [2,1,2,6]
Output: false
Example 3:
Input: [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].
Example 4:
Input: [1,2,4,16,8,4]
Output: false
其他說明:
0 <= A.length <= 30000
A.length is even
-100000 <= A[i] <= 100000
題目分析:
這道題是陣列內滿足某條件的元素是否存在的問題。
這道題是來判斷是否陣列內的全部元素都可以組成(x,2x)這樣的元組。
如 [16,8,32,4]就可以組成(4,8)、(16,32)。
思路
對陣列各個元素出現的個數計數,x為某元素值,counter[x]是該元素出現次數。
按照元素絕對值從小到大排序,判斷counter[2*x]是否大於counter[x],如果counter[2*x] > =counter[x], 可以確定形成 counter[x] 個(x,2*x)個對。
因為按照絕對值從小到大排序後,當遍歷到某元素A[i]時,陣列中A[i]/2要麼不存在,要麼已經和A[i]/4成對,也就是說不能再使用了。對於A[i], 當且僅當陣列中存在A[i]*2條件才可以滿足,考慮到有重複元素的情況,counter[A[i]] <= counter[A[i]*2]
資料結構
根據場景選擇資料結構:
python: collections.counter() python中的計數器
返回dict型別:key為元素值,value為元素出現的個數。
c++、java:Map儲存元素及計數結果
python實現:
class Solution:
def canReorderDoubled(self, A):
c = collecitons.counter(A)
for i in sorted(c,key=lamda x : abs(x)):
if c[i] > c[2*i]:
return False
else:
c[2*i]-=c[i]
其中sorted 函式內部是Timsort排序演算法,結合了合併排序(merge sort)和插入排序(insertion sort)。最壞情況下時間複雜度為O(nlogn),當待排序的陣列中已經有排序好的數,它的時間複雜度會小於n logn。