題目連結:
題目意譯:
你被給定一個已排序陣列,其只由整數組成且每個元素出現恰好兩次,除了其中一個只出現恰好一次。找到這個只出現一次的單一元素。
進階: 你的解法應為 O(log n) 時間複雜度且為 O(1) 空間複雜度。
限制:
1 ≦ nums.length ≦ 10 ^ 5
0 ≦ nums[i] ≦ 10 ^ 5
範例測資:
範例 1:
輸入: nums = [1,1,2,3,3,4,4,8,8]
輸出: 2
範例 2:
輸入: nums = [3,3,7,7,10,11,11]
輸出: 10
解題思維:
雖然
這題的作法可行,但是該作法的時間複雜度為 O(n)。
而因為 nums 已排序了,因此我們可以利用二分搜尋法(Binary Search)來解出這題。定義下界 L = 0(nums 的索引值從 0 開始)、上界 U = nums.length。然後重複以下步驟直到 R - L ≦ 1:
求出 M = floor((L + R) ÷ 2),其中 floor() 為下高斯函數(對於正數等價於無條件捨去小數點)。此時如果 M 是奇數便將 M 減去 1。
因此現在可以看到位於 nums[M] 左側之元素恰好有 M 個,且 M 為一個偶數。而如果所有元素都恰好出現偶數次,則 nums[M] 左側的元素應可以兩兩成對,而更重要的是——nums[M] 應等於 nums[M + 1]。
所以當 nums[M] = nums[M + 1] 時,我們便可以看到範圍 [L, M + 1] 都不會有我們要的元素。因此我們將下界更新為 L = M + 2;而一旦 nums[M] ≠ nums[M + 1] 時,則代表所求元素位於 [L, M] 這個範圍之內,因此上界更新為 U = M + 1。
因此最後過程結束後的 L 值,即代表著 nums[L] 是我們所求的元素。所以回傳 nums[L] 即可。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。