1. 程式人生 > >【死磕演算法之1刷leetcode】954. Array of Doubled Pairs

【死磕演算法之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。