LeetCode: Single Number 系列

136.找出給定列表中落單的整數

Question:
Given a non-empty array of integers, every element appears twice except for one. Find that single one.
Example:

Input: [2,2,1]
Output: 1

果然是屬于 easy 的題目簿透。很簡單嘛椎木。2秒鐘后踪区。。径密。

class Solution:
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        for i in nums:
            if nums.index(i) + nums[::-1].index(i) == len(nums)-1:
                return i

在線測試 finished 只用了三行代碼就搞定了,可把我牛逼壞了,哈哈
果斷提交WTF... 失敗了,提示:Time Limit Exceeded 怎么回事毯欣,原來是代碼運行時間太長不符合leetcode檢測要求。繼續(xù)看題目要求:
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

要求:您的算法應該具有線性運行時復雜度O(n)

嗯什么是時間復雜度O(n)與O(1)臭脓。大學也曾知道過,可惜都還給書本了腹忽,哎来累,百度一下 --- 授人以魚不如授人以漁,給你一本數據結構的書就懂了 ---mdzz
正確的姿勢如下:

引用一位大佬的解釋:
舉個簡單的例子窘奏,要從0加到n嘹锁,我們會這么寫:
int sum = 0;
for(int i = 0; i<=n; ++i)
{
   sum += i;
}
一共算了n次加法,那么就說這個時間復雜度是O(n)着裹。當然O(n)的精確的概念是领猾,是n的最高次方,比如,某個計算共計算了3n + 2次摔竿,那么這個時間復雜度也是O(n)面粮,因為3n + 2中的最高次方是n。

如果代碼這么寫:
int sum = 0;
for(int i = 0; i<=n; ++i)
{
   for(int j = 0; j <=n; ++j)
   {
      sum += (i + j);
   }
}

很顯然一共算了n^2次加法继低,那么就說這個時間復雜度是O(n^2)熬苍,和上面類似,如果某個算法計算了3*n^2 + n + 1次袁翁,其時間復雜度仍然是O(n^2)柴底,因為3*n^2 + n + 1中最高的次方是n^2

所謂O(1)就是計算的次數是個常量,我們還以上面從0加到n的例子來說粱胜,如果我們用等差數列的公式柄驻,那么,代碼可以這么寫:
int sum = n * (n + 1) / 2
不管n有多大(當然不能溢出了)焙压,通過上面的公式只需計算一次鸿脓,也就說計算的次數是不變的,這種情況的時間復雜度就可以說成O(1)冗恨。 再比如如果某個計算答憔,不管其他條件怎么變化,均只需計算5次即可得出結果掀抹,那么這種情況的時間復雜度虐拓,也是O(1)。

怎么樣懂了吧傲武,本來還想試圖分析下蓉驹,還是算了。上面已經解釋的夠清晰了揪利,不添亂了态兴。果然 leetcode 還是有貨的,不能只學代碼疟位,否則就真成碼農了瞻润,反思下~~~
現在知道了自己的錯誤在哪里。繼續(xù)重新編輯:

class Solution:
    def singleNumber(self, nums):
        #52ms
        nums.sort()
        num = 0
        j = 0
        for i in nums:
            if j%2 == 0:
                num += i
            else:
                num += -i
            j += 1
        return num
        
        #48ms
        nums.sort()
        for i in range(len(nums)//2):
            if nums[-1] != nums[-2]:
                return nums[-1]
            nums.pop()
            nums.pop()
        return nums[0]

使用了倆種方式第一種52ms 第二種48ms 代碼很簡單甜刻,不需要解釋吧绍撞。其中nums.sort()的時間復雜度應該也是O(n)具體算法,以后有機會在分析得院,所函數總的時間復雜度也是O(n)符合要求傻铣。
1: nums.sort([reverse=True]) 會將nums列表正序排序,參數reverse=True 時會逆序排序
2: sorted(nums) 會返回一個新的序列祥绞。該函數可用于任何可迭代對象非洲,也存在reverse參數

來感受下官方給出的解決方案:Solution

前倆種方法不做分析鸭限,主要看一下。方法3和4两踏, 來感受一下數學的魅力

數學計算: 2?(a+b+c)?(a+a+b+b+c)=c

class Solution(object):
    def singleNumber(self, nums):
        return 2 * sum(set(nums)) - sum(nums)

位運算: a⊕0=a a⊕a=0 a⊕b⊕a=(a⊕a)⊕b=0⊕b=b

⊕ 表示異或運算(按位相異為1 相同為0) XOR 舉個栗子:

2         0000 0010
0         0000 0000
2 xor 0 = 0000 0010 = 2
3         0000 0101
3         0000 0101
3 xor 3 = 0000 0000 = 0
a⊕b⊕a=(a⊕a)⊕b=0⊕b=b 交換律請自行驗證

另外在python中有如下語法:
+, -, *, /, //, **, ~, %分別表示加法或者取正败京、減法或者取負、乘法缆瓣、除法喧枷、整除、乘方弓坞、取補隧甚、取模。>>, <<表示右移和左移渡冻。&, |, ^表示二進制的AND, OR, XOR運算戚扳。>, <, ==, !=, <=, >=用于比較兩個表達式的值,分別表示大于族吻、小于帽借、等于、不等于超歌、小于等于砍艾、大于等于。在這些運算符里面巍举,~, |, ^, &, <<, >>必須應用于整數脆荷。 Python使用and, or, not表示邏輯運算。

class Solution(object):
    def singleNumber(self, nums):
        a = 0
        for i in nums:
            a ^= i
        return a

因為有a⊕b⊕a=(a⊕a)⊕b=0⊕b=b交換律存在懊悯,對所有數進行異或運算其中相同的2個數最終得到0蜓谋,最后運算結果為落單的數。
果然這才是程序猿該有的姿勢炭分,linux中一切皆文件桃焕。python中一切皆對象。但終究一切皆數學啊~~

接下來再嘗試下Single Number的升級版:

137.Single Numver II 也是找落單的數

question:
Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
example:

Input: [2,2,3,2]
Output: 3

有了上面的基礎捧毛,這道題還是挺簡單的观堂。數學解法:3(a+b+c)-(3a+3b+c) = 2c

class Solution:
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        return (3*sum(set(nums)) - sum(nums))//2

完美通過。官方沒有給出標準的解決方案呀忧,本來還是想看看類似bit操作的解法型将,無奈搜了一下感覺很難,先這樣荐虐,我還有其他事要做,不能浪費在這丸凭。此處貼上解法的鏈接福扬,如果朋友們有興趣請自行研究腕铸,再來看看變種3

260.Single Numver III 找多個出現一次的數

question:
Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
example:

Input:  [1,2,1,3,2,5]
Output: [3,5]

仔細想了一番。暫時不能通過數學方法來得出結論铛碑。就用傳統(tǒng)的方法吧狠裹。而且該方法也比較通用,不論是針對整數的列表,還是針對字符串的列表都可以使用汽烦,大家可以使用該方法涛菠,以此將上面的題目實現一邊

class Solution:
    def singleNumber(self, nums):
        res_dir = {}
        for i in nums:
            if i not in res_dir:
                res_dir[i] = 1
            else:
                del res_dir[i]
        res = []
        for key in res_dir:
            res.append(key)
        return res

很簡單的方法,一看代碼就清楚了撇吞。我想該題也有類似bit運算的解法俗冻。如有同學知道。還請賜教~~謝謝牍颈,Single Number 系列就先到這里

總結:

  • 關于時間復雜度 O(n) 的定義
  • 關于python中的一些位運算符
  • 關于異或運算的規(guī)律
  • 關于這種題的通用解法
  • 巧用數學方法解題

聲明:

本人也是python 小白迄薄,如果上述內容有講的不對的地方還請各位批評指點。將不勝感激煮岁,再次感謝~~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末讥蔽,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子画机,更是在濱河造成了極大的恐慌冶伞,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,835評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件步氏,死亡現場離奇詭異响禽,居然都是意外死亡,警方通過查閱死者的電腦和手機戳护,發(fā)現死者居然都...
    沈念sama閱讀 89,900評論 2 383
  • 文/潘曉璐 我一進店門金抡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腌且,你說我怎么就攤上這事梗肝。” “怎么了铺董?”我有些...
    開封第一講書人閱讀 156,481評論 0 345
  • 文/不壞的土叔 我叫張陵巫击,是天一觀的道長。 經常有香客問我精续,道長坝锰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,303評論 1 282
  • 正文 為了忘掉前任重付,我火速辦了婚禮顷级,結果婚禮上,老公的妹妹穿的比我還像新娘确垫。我一直安慰自己弓颈,他們只是感情好帽芽,可當我...
    茶點故事閱讀 65,375評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翔冀,像睡著了一般导街。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纤子,一...
    開封第一講書人閱讀 49,729評論 1 289
  • 那天搬瑰,我揣著相機與錄音,去河邊找鬼控硼。 笑死泽论,一個胖子當著我的面吹牛,可吹牛的內容都是我干的象颖。 我是一名探鬼主播佩厚,決...
    沈念sama閱讀 38,877評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼说订!你這毒婦竟也來了抄瓦?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,633評論 0 266
  • 序言:老撾萬榮一對情侶失蹤陶冷,失蹤者是張志新(化名)和其女友劉穎钙姊,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體埂伦,經...
    沈念sama閱讀 44,088評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡煞额,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,443評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了沾谜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膊毁。...
    茶點故事閱讀 38,563評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖基跑,靈堂內的尸體忽然破棺而出婚温,到底是詐尸還是另有隱情,我是刑警寧澤媳否,帶...
    沈念sama閱讀 34,251評論 4 328
  • 正文 年R本政府宣布栅螟,位于F島的核電站,受9級特大地震影響篱竭,放射性物質發(fā)生泄漏力图。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,827評論 3 312
  • 文/蒙蒙 一掺逼、第九天 我趴在偏房一處隱蔽的房頂上張望吃媒。 院中可真熱鬧,春花似錦、人聲如沸晓折。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,712評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漓概。三九已至,卻和暖如春病梢,著一層夾襖步出監(jiān)牢的瞬間胃珍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,943評論 1 264
  • 我被黑心中介騙來泰國打工蜓陌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留觅彰,地道東北人。 一個月前我還...
    沈念sama閱讀 46,240評論 2 360
  • 正文 我出身青樓钮热,卻偏偏與公主長得像填抬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子隧期,可洞房花燭夜當晚...
    茶點故事閱讀 43,435評論 2 348

推薦閱讀更多精彩內容

  • 聽過很多模樣的鐘先生飒责。他兄弟嘴里“一條徹頭徹尾的狗”的鐘先生,啊鼎嘴里“一個喜歡走不尋常路的鐘少”的鐘先生仆潮,會長嘴...
    風如斯閱讀 322評論 0 0
  • 隨著《我們相愛吧之愛有天意》的收官宏蛉,大家對無尾熊的關注度有增無減,我也和你一樣多么希望節(jié)目過后他倆依然能在一起性置。 ...
    喵了個說職場閱讀 633評論 5 6
  • 你走之后 我仍然會準時起床睡覺 仍然會去我喜歡的飯店吃飯 周末還是會和朋友K歌聊天喝到爛醉 我還記得你的名字 我卻...
    求生的刻舟人閱讀 795評論 0 1
  • 啦啦啦
    036a380169a1閱讀 75評論 0 1