Task01部分自己沒注意到的點
1、is,is not對比的是兩個變量的內(nèi)存地址,==,!=對比的是兩個變量的值。
假如比較的兩個變量,指向的都是地址不可變的類型(str等),那么is,is not和==,!=是完全等價的。
假如對比的兩個變量,指向的是地址可變的類型(list,dict,tuple等),則兩則是有區(qū)別的。
eg:比較的兩個變量均指向不可變類型
a = "hello"
b = "hello"
print(a is b,a==b)
True True
比較的兩個變量均指向可變類型
a = ["hello"]
b = ["hello"]
print(a is b,a==b)
False True
2、運算符的優(yōu)先級
1)、一元運算符優(yōu)于二元運算符。如正負號。
2)、先算術(shù)運算,后移位運算,最后位運算。例如1<<3+2 & 7等價于(1<<(3+2)) & 7。
3)、邏輯運算最后結(jié)合。
eg:
print(-3 ** 2) # -9
print(3 ** -2) # 0.111111111111111
print(-3 * 2 + 5 / -2 -4) # -12.5
print(3<4 and 4<5) #True
3、利用位運算實現(xiàn)整數(shù)集合
一個數(shù)的二進制表示可以看作是一個集合(0表示不在集合中,1表示在集合中)。
比如集合{1,3,4,8},可以表示成01 00 01 10 10而對應(yīng)的位運算也就可以看作是對集合進行的操作。

關(guān)于很大的整數(shù)怎么表示:
uint 是32為的 能夠表達 0~31 這樣表示集合 可以節(jié)省內(nèi)存。而且利用位運算可以進行 集合的交集 并集 差集等運算。
用 uint[] 的數(shù)組來處理就好。 比如最大的數(shù)是60,用兩個無符號整數(shù)就可以了。
2、練習(xí)題
leetcode習(xí)題136,只出現(xiàn)一次的數(shù)字。
給定一個非空整數(shù)數(shù)組,除了某個元素只出現(xiàn)一次以外,其余每個元素均出現(xiàn)兩次。找出那個只出現(xiàn)了一次的元素。
解題思路:
如果沒有時間復(fù)雜度和空間復(fù)雜度的限制,這道題有很多中解法,可能的解法有如下幾種:
1、使用集合存儲數(shù)字。遍歷數(shù)組中的每個數(shù)字,如果集合中沒有該數(shù)字,則將該數(shù)字加入集合,如果集合中已經(jīng)有該數(shù)字,則將該數(shù)字從集合中刪除,最后剩下的數(shù)字就是只出現(xiàn)一次的數(shù)字。
2、使用哈希表存儲每個數(shù)字和該數(shù)字出現(xiàn)的次數(shù)。遍歷數(shù)組即可得到每個數(shù)字出現(xiàn)的次數(shù),并更新哈希表,最后遍歷哈希表,得到出現(xiàn)一次的數(shù)字。
3、使用集合存儲數(shù)組中出現(xiàn)的所有數(shù)字,并計算數(shù)組中的元素之和。由于集合保證元素無重復(fù)因此計算集合中的所有元素之和的兩倍,即為每個元素出現(xiàn)兩次的情況下的元素之和。由于數(shù)組中只有一個元素出現(xiàn)一次,其余元素都出現(xiàn)兩次,因此用集合中的元素之和的兩倍減去數(shù)組中的元素之和,剩下的數(shù)就是數(shù)組中只出現(xiàn)一次的數(shù)字。
上述三種解法都需要額外的使用O(n)的空間,其中n是數(shù)組長度。如果要求使用線性時間復(fù)雜度和常數(shù)空間復(fù)雜度,上述三種解法顯然都不滿足要求。那么只能運用位運算。而且是用⊕,異或。
異或運算有以下三個性質(zhì):
1)、任何數(shù)和0做異或運算,結(jié)果仍然是原來的數(shù),即a⊕0=a
2)、任何數(shù)和其自身做異或運算,結(jié)果是0,即a⊕a=0
3)、異或運算滿足交換律和結(jié)合律,即a⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b
代碼如下:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
ans = 0
for i in nums:
ans^=i
return ans
復(fù)雜度分析:時間復(fù)雜度:O(n),其中n是數(shù)組長度。只需要對數(shù)組遍歷一次。
空間復(fù)雜度:O(1)