Leetcode 137:只出現一次的數字 II(最詳細的解法!!!)
給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現了三次。找出那個只出現了一次的元素。
說明:
你的演算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?
示例 1:
輸入: [2,2,3,2]
輸出: 3
示例 2:
輸入: [0,1,0,1,0,1,99]
輸出: 99
解題思路
這是之前Leetcode 136:只出現一次的數字(最詳細的解法!!!)問題的擴充套件。我們直接使用xor
的方法不行,因為我們這裡是三個元素,所以我們無法完成消除。但是我們可以通過dict
記錄元素個數,最後判斷出現次數為1
的是誰即可。
class Solution:
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_dict = {}
for num in nums:
nums_dict[num] = nums_dict.get(num, 0) + 1
for key, val in nums_dict.items():
if val == 1:
return key
我們如果不是用額外空間怎麼做呢?我們可以使用set
得到nums
中所有不重複的元素,通過這些不重複的元素和的三倍減去原來nums
的和,得到的結果就是單個元素的兩倍。
class Solution:
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return (3*sum(set(nums)) - sum(nums))//2
這個問題其實還是可以通過邏輯運算來解決。我們想一想我們之前Leetcode 268:缺失數字(最詳細的解法!!!)中的做法,為什麼要使用xor
?其本質就是想通過兩個元素相互消除。那麼我們這個問題其實本質就是希望三個元素相互消除。那麼這要怎麼做呢?我們不再是通過一個元素記錄狀態,我們可以通過兩個元素來記錄狀態的轉化,例如
a b
0 0 0
1 x 0
2 0 x
3 0 0
首先我們會定義兩個變數a
和b
,當遍歷nums
的時候,對於重複元素x
,第一次碰到x
的時候,我們會將x
賦給a
,第二次碰到後再賦給b
,第三次碰到就全部消除。賦值和消除的動作可以通過xor
很簡單的實現。所以我們就可以寫出這樣的程式碼
a = (a^num)
b = (b^num)
但是上面寫法忽略了,只有當a
是x
的時候,我們會將0
賦給b
,那要怎麼做呢?我們知道如果b=0
,那麼b^num
就變成了x
,而x&~x
就完成了消除操作,而此時a=x
,所以第二行寫為
b = (b^num) & ~a
同理,我們應該將第一行改為
a = (a^num) & ~b
最後程式碼如下
class Solution:
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
ones, twos = 0, 0
for num in nums:
ones = (ones^num) & ~twos
twos = (twos^num) & ~ones
return ones
如果我們將問題繼續推廣成如果輸入陣列中每個元素出現k次,只有一個元素出現p次,那個出現p次的元素是?
看這篇尋找特定數字問題
reference:
我將該問題的其他語言版本新增到了我的GitHub Leetcode
如有問題,希望大家指出!!!
相關文章
- LeetCode 只出現一次的數字IILeetCode
- 只出現一次的數字 II
- LeetCode 只出現一次的數字LeetCode
- Leetcode 169:求眾數(最詳細的解法!!!)LeetCode
- LeetCode 136. 只出現一次的數字【c++/java詳細題解】LeetCodeC++Java
- LeetCode 只出現一次的數字IIILeetCode
- Leetcode 253:Meeting Rooms II(超詳細的解法!!!)LeetCodeOOM
- LeetCode之只出現一次的數字-SwiftLeetCodeSwift
- LeetCode136 只出現一次的數字LeetCode
- leetcode136. 只出現一次數字LeetCode
- leetcode力扣136.只出現一次的數字LeetCode力扣
- LeetCode每日一題:只出現一次的數字(No.136)LeetCode每日一題
- 136只出現一次的數字
- LC-出現一次的數字II
- 136. 只出現一次的數字
- 只出現一次的數字--力扣力扣
- 找出陣列中只出現一次的數字陣列
- 力扣136.只出現一次的數字力扣
- Leetcode 137. Single Number IILeetCode
- JZ-040-陣列中只出現一次的數字陣列
- Leetcode 167:兩數之和 II - 輸入有序陣列(最詳細解決方案!!!)LeetCode陣列
- Leetcode 960:刪列造序 III(超詳細的解法!!!)LeetCode
- [演算法練習及思路-leetcode劍指offer(Java解法)]No50.第一個只出現一次的字元演算法LeetCodeJava字元
- 在其它數都出現k次的陣列中找到只出現一次的數陣列
- 第一次只出現一次的字元字元
- 137-Single Number II
- 最難數獨的快速解法 - pythonPython
- LeetCode題解:264. 醜數 II,二叉堆,JavaScript,詳細註釋LeetCodeJavaScript
- Leetcode 通過率最高的困難題 N皇后 II 【回溯解法-剪枝】LeetCode
- 第一個只出現一次的字元——Java字元Java
- 264、醜數 II | 演算法(leetcode,附思維導圖 + 全部解法)300題演算法LeetCode
- LeetCode 每日一題,用 Go 實現兩數之和的非暴力解法LeetCode每日一題Go
- 給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。陣列
- openstack完整的部署(最詳細)
- 全網最詳細的ReentrantReadWriteLock原始碼剖析(萬字長文)原始碼
- 每日一練(23):第一個只出現一次的字元字元
- JZ-034-第一個只出現一次的字元位置字元
- 508、出現次數最多的子樹元素和 | 演算法(leetcode,附思維導圖 + 全部解法)300題演算法LeetCode