1. leetcode 242.有效的字母異位詞
題目連結:242. 有效的字母異位詞 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:學透雜湊表,陣列使用有技巧!Leetcode:242.有效的字母異位詞_嗶哩嗶哩_bilibili
自己的思路:首先就是對字串進行分開成一個一個單獨的字母,然後使用列表儲存這些資料,再對這個資料進行排序,排序完後就輸出兩個字串相等或者不等的值
1.1 自己寫的程式碼
自己做題的思路就是暴力搜尋,呼叫內部的函式進行計算
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
s.split()
t.split()
s_l = list(s)
t_l = list(t)
s_l.sort()
t_l.sort()
return s_l== t_l
1.2 雜湊表的方法
1.2.1雜湊表的思路
-
字串總共有26個,所以建立一個可以容納26個字串的雜湊表,初始值為0
-
統計第一個字串
s
中每個字母出現的次數,這裡計算就是用字串位置減去第一個字母即'a'
的值,計算兩個字串的值在python中轉化為對ASCII碼計算,函式是ord()
,然後就是統計每個字串出現的次數,對其數值進行相加 -
對第二個字串
t
中的資料對雜湊表進行一個減法的操作 -
對字串中的字元進行迴圈,如果雜湊表的值有不等於
0
的,則證明兩個字串不相等,否則就是相等
1.2.2 雜湊表的程式碼
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
record = [0]*26
for i in s:
record [ord(i)-ord('a')] +=1
for j in t:
record [ord(j)-ord('a')]-=1
for i in range(26):
if (record[i]!=0):
return False
return True
1.3 本題小結
- 定義雜湊表為陣列的方法:
recode= [0]*26
- 這種題一般就是會有一個簡單的思路來做,但是這種思路的缺點就是計算時間會比較久,用雜湊表的方法會節省很多的計算時間
2. leetcode 349.兩個陣列的交集
題目連結:349. 兩個陣列的交集 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:學透雜湊表,set使用有技巧!Leetcode:349. 兩個陣列的交集_嗶哩嗶哩_bilibili
自己的思路:首先就是建立一個空列表,然後對第一個列表裡面的資料進行迴圈,如果第一個列表的資料在第二個列表中,就對空列表進行資料增加,最後使用set對其進行去重,輸出
2.1 自己的思路
這種方法有一種暴力搜尋的感覺
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
l = list()
for i in nums1:
if i in nums2:
l.append(i)
return list(set(l))
2.2 雜湊表的方法
這道題資料最長在1000,所以進行雜湊表的時候其實使用set和陣列都是可以的
2.2.1 set雜湊表的方法
發現python中直接使用集合的方式真的簡單
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return list(set(nums1) & set(nums2))
2.2.2 雜湊表陣列的方式
fun1
思路:
- 首先建立兩個空陣列,初始值都為0
- 對兩個陣列進行判斷,然後儲存至這個空列表中
- 出錯點:如何判斷這兩個已有陣列的值是否相等,不是對其直接進行等於,這樣沒有用的雜湊表的值也會進行相加,所以這裡就是對二者的數值進行乘,然後判斷有的話進行列表陣列加,沒有則繼續迴圈
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
num_l1 = [0]*1005
num_l2 = [0]*1005
result = []
for i in nums1:
num_l1[i] +=1
for j in nums2:
num_l2[j] +=1
for k in range(1005):
if num_l1[k]*num_l2[k]>0:
result.append(k)
return result
fun2
思路:
- 建立一個空集合
- 對第一個陣列的數進行迴圈,然後將其值新增值雜湊表中
- 對第二個陣列的值進行判斷,如果第二個值的索引值和雜湊表中規定的值相等,在空集合中新增第二個陣列的下標
- 最後對這個集合使用列表進行返回即可
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
set_num = set()
num = [0]*1005
for i in nums1:
num[i] = 1
for j in nums2:
if num[j]==1:
set_num.add(j)
return list(set_num)
2.3 本題小結
- 集合方式在python中非常簡單,即判斷兩個集合的交集即可進行輸出
- 陣列的方式則很重要的一點就是陣列啥時候對資料相加,則是其值相乘大於0的時候。
3. leetcode 202.快樂數
題目連結:202. 快樂數 - 力扣(LeetCode)
文章連結:程式碼隨想錄
自己的思路:首先就是有一個東西去儲存,儲存的是n
的每個位數數值平方的和,然後對這個資料進行判斷,如果等於1了就返回真,否則就返回假。但是自己無法編譯出來,其實,,,
3.1 集合的思路
思路:
- 首先就是計算這個每位數平方的和
- 建立一個空集合,進入迴圈體內部,如果其值為1,返回True
- 如果這個值不為1,首先看看這個值在不在建立的集合中,如果在就輸出False,陷入死迴圈了,否則就將這個輸出值加入到所建立的集合中
class Solution:
def isHappy(self, n: int) -> bool:
record = set()
while True:
n = self.get_sum(n)
if n==1:
return True
if n in record:
return False
else:
record.add(n)
def get_sum(self,n: int) -> int:
new_num =0
while n:
n,r = divmod(n,10)
new_num +=r**2
return new_num
3.2 陣列的思路
這種方法的精髓就在於將這個數字轉換成字串,然後在迴圈內部對其進行相乘,判斷其值是否符合要求
class Solution:
def isHappy(self, n: int) -> bool:
record = []
while n not in record:
record.append(n)
new_sum = 0
n_str = str(n)
for i in n_str:
new_sum += int(i)**2
if new_sum == 1:
return True
else:
n = new_sum
return False
3.3 本題小結
- 計算一個數字的整數部分和餘數部分,在python中可以使用
divmod
函式,例如m,n=divmod(23,10)
,那麼m=2,n=3
,這個就是計算方法 - 其他的需要注意就是將已經算出的新的sum值進行增加到列表或者集合中,如果在裡面出現了相同的值,可以判斷出這個程式碼已經死迴圈,則可以結束了
4. leetcode 1.兩數之和
題目連結:349. 兩個陣列的交集 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:學透雜湊表,set使用有技巧!Leetcode:349. 兩個陣列的交集_嗶哩嗶哩_bilibili
自己的思路:首先就是對nums進行迴圈,然後再使用第二層迴圈從第一層迴圈的後面開始走,如果找到了一個i+j的數與目標值相等,則輸出這個值即可
4.1 第一次寫的程式碼
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i]+nums[j] ==target:
return [i,j]
4.2 雜湊表的寫法
思路:
- 這道題返回的是值的下標,即索引位置,所以就想到了每個值對應一個下標,即鍵值對的對應關係
- 鍵值對就使用字典的方式,返回值為字典中的值
- 那麼就對nums進行一個迴圈,迴圈包含其值和下標,所以使用
enumerate
函式,這樣迴圈過程有兩個數,下標和值本身 - 判斷所需要兩個值是否在裡面呢,就需要進行一個計算,已知
target
的值,所以減去現在索引處的值,看得到的那個值在不在字典中,在就返回這兩個的索引值 - 否則就將這個數值和索引值加到字典中
4.2.1字典的方法
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
recorde = dict()
for index,value in enumerate(nums):
if target-value in recorde:
return [recorde[target-value],index]
recorde[value] = index
return []
4.2.2 集合的方法
這個方法有點繞,就是找值對應的索引,所以需要用到index
函式。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
recorde = set()
for i,value in enumerate(nums):
complement = target-value
if complement in recorde:
return [nums.index(complement),i]
recorde.add(value)
return []
4.3 本題小結
- 這道題主要掌握的思路就是字典的查詢,明白這裡面儲存的值是什麼值,一般情況下其內部所儲存的值為鍵和值
- 為什麼這道題索引為值,數值為鍵:因為我們要進行計算,判斷過程就是看鍵在不在這個字典中,如果在的話再返回鍵所對應的值,所以這麼選擇
5 本章小結
5.1 選擇雜湊表的方法
- 雜湊表一般出現在列表集合和字典中,就是對值和索引有要求的時候是較好用的一種方法
- 列表:選擇這個的時候,是因為其資料內部的長度較短,不會報索引太長的時候用這種方法最簡單,一般就是比較一個陣列中的數是不是在另一個陣列,有多少在裡面的情況
- 集合:選擇集合就是真內部需要儲存的資料足夠的長,而且要求內部不重複的話會很好用
- 字典:這個時候就是即需要對值和下標都有判斷的時候,就比較好用,例如兩數之和的題目,對鍵進行判斷其值,返回的是其所對應的值
5.2 python中的一些函式
- 計算一個值的整數和餘數部分的方法
r,n=divmod(23,10)
,這個就是計算23/10的整數和餘數,r=2,n=3
- 計算一個值的ASCII碼的函式
ord(a)
是計算ASCII中的數值 - 在集合中新增陣列方式
set().add(1)
就是將1新增到集合中 - 兩集合的交集的求法
set(a) & set(b)
- 對字典新增資料的方法
num = dict(), num[key]=val
- 索引陣列中值對應的下標
num.index[1]
就是索引數值1在列表中的索引位置