242. 有效的字母異位詞
?nums = [0]*26
?:
這行代碼創建了一個包含26個0的列表,這個列表通常用于計數或者作為某種映射的基礎,比如統計字符串中每個字母出現的次數(假設只考慮小寫字母a-z)。
ord()
Python 中的一個內置函數,用于獲取單個字符(Unicode 字符)的整數表示(即字符的 Unicode 碼點)。這個函數非常有用,因為它允許你將字符與其在計算機內部存儲的數值表示形式相互轉換。
ord(c):c
?是一個長度為 1 的字符串,即一個字符
# 獲取字符 'A' 的 Unicode 碼點
print(ord('A')) # 輸出: 65 # 獲取數字字符 '5' 的 Unicode 碼點
print(ord('5')) # 輸出: 53 # 嘗試獲取多字符字符串的 Unicode 碼點,將拋出 TypeError
# print(ord('AB')) # TypeError: ord() expected a character, but string of length 2 found # 嘗試獲取非字符字符串(如空字符串)的 Unicode 碼點,也將拋出 TypeError
# print(ord('')) # TypeError: ord() expected a character, but string of length 0 found
注意事項
ord()
?函數僅適用于單個字符的字符串。- 字符的 Unicode 碼點可以用來在程序中進行各種操作,比如字符編碼轉換、字符比較等。
- 當你需要將一個整數轉換回對應的字符時,可以使用內置的?
chr()
?函數。
python 代碼:
class Solution:def isAnagram(self, s: str, t: str) -> bool:nums = [0]*26for i in s:nums[ord(i)-ord('a')] += 1for i in t:nums[ord(i)-ord('a')] -= 1for i in nums:if i != 0:return Falsereturn True
349. 兩個數組的交集
當數組中的數值沒有小于1000這個限制的時候,這道題傾向于用set來求解。加了這個限制之后,這道題目用數組來求解,用哈希表的結構是比較合適的。當我們遇到哈希表的題目的時候,要判斷什么時候用數組?什么時候用set?什么時候用map?
這里我們默認他沒有加上數組的限制。也就是其中的Int可能非常大。可能是上千或上億。當這里面的數值非常大的時候,我們想用數組來做映射就不合適了。因為數組下標放不了那么大的數。同時也非常浪費儲存空間。
這道題為什么會想到用哈希表來解決?哈希表適合用于解決什么樣的題目?哈希表最擅長于解決,給你一個集合,判斷元素是否有在這個集合里出現過。類似這種場景第一個要想到用哈希表。具體用數組還是用set還是用map?要具體分析。如果這個數值很大的話就不適合用數組。還有一種情況是數值可能不是很大,但是分布的很分散。如0,100萬,如果用數組來做映射的話,要用100萬那么大的數組,但實際運用的只有三個。這種情況下用set也是比較合適的。
本題是求兩個數組的交集。可以將其中一個數組轉化為哈希表。然后再去遍歷第二個數組,檢查元素是否在哈希表里面出現過。如果出現過,我們就將它放在result集合里面,并且這個集合是去重的。
在c加加里面有三個set結構:
以下是幾個與集合相關的常用C++ STL(標準模板庫)容器:
-
std::set
std::set
?是一個基于紅黑樹(一種自平衡二叉查找樹)實現的集合容器。它存儲的元素是唯一的,且按照一定的順序(默認情況下是升序,但可以通過自定義比較函數來改變)進行存儲。std::set
主要提供了插入、刪除和查找元素的操作,這些操作在平均和最壞情況下都具有對數時間復雜度。 -
std::multiset
與
std::set
類似,std::multiset
也是基于紅黑樹實現的,但它允許存儲重復的元素。這意味著同一個值可以在std::multiset
中出現多次。std::multiset
提供的接口和操作與std::set
類似,但考慮到它允許重復元素,其行為在某些方面會有所不同(比如插入重復元素時,會成功添加而不是失敗)。 -
std::unordered_set
與
std::set
和std::multiset
不同,std::unordered_set
是基于哈希表實現的,因此它不保證元素的順序。然而,由于哈希表的性質,它在平均情況下的插入、刪除和查找操作都具有常數時間復雜度(盡管在最壞情況下可能會退化到線性時間復雜度,但這通常不會發生)。std::unordered_set
同樣要求存儲的元素是唯一的。
需要注意的是,雖然這里沒有直接提到“三個set結構”的固定術語,但std::set
、std::multiset
和std::unordered_set
是C++ STL中與集合操作最相關的三種數據結構。它們各自的特點和用途使得開發者可以根據具體需求選擇最適合的數據結構。
std::set
、std::multiset底層實現都是紅黑樹。std::unordered_set底層實現是哈希值的方式。是哈希值直接映射,可以理解為是一個可以無限存儲的數組。這里選擇unordered_set,因為他做映射的時候效率是最高的。做取值操作的時候效率也是最高的。因為另外兩個底層是樹,取值的時候還有一個查找的操作。
set解決:unordered_set = result
因為unordered_set 可以進行去重操作,從這里也可以看出來,我們在解題的時候選擇一個合適的數據結構非常重要。
unordered_set = number_set(nums1)
這里直接將nums1進行初始化。將nums1轉化為unordered_set ;接下來這里對nums2進行一個查詢操作。for(i = 0;i<nums2.size;i++){
遍歷的過程首先是判斷這個元素在unordered_set 里面有沒有出現過。if (number_set.find(nums2[i] != number_set.end()){
在這段C++代碼中,number_set.find(nums2[i]) 返回一個迭代器,指向找到的元素(如果找到的話),或者如果沒有找到,則返回 end() 迭代器。然后,我們通過比較這個迭代器是否不等于 end() 迭代器來檢查元素是否存在。result.insert(nums2[i])
}return vector(result)數組解決:
我們定義一個數組,比給定的范圍大一點就行了。
int hash[1005] = {0}
unordered_set = result
還是剛才的處理邏輯,首先將nums1處理成哈希表的結構。for(i = 0;i<nums1.size;i++){hash[nums1[i]] = 1;哈希數組下標所對應的值賦值為一,這樣我們這個哈希數組就記錄了nums1數組中的所有元素。所有出現過的元素在我數組的下標所對應的值都是一。這樣就將數組nums1中所有元素進行記錄了。
}接下來是判斷nums2for(i = 0;i<nums2.size;i++){if (hash[nums2[i] == 1]){如果這個值等于一,說明他在哈希表里出現過。result.insert[num2[i];這樣就將nums1出現過的元素,在num2中間儲存起來了。并且進行了去重的操作
}
}
return vector(result)其實這道題用數組來做效率會更高一些,因為用set的話每往里面添加一個值,進行一個insert的操作,要對值進行一個哈希運算。然后轉變成他內部存儲的值,然后還要去新開辟一個內存空間。用數組的話直接用下標進行哈映射是最快的。
Python代碼(set方法):
class Solution:def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:return list(set(nums1) & set(nums2))#使用 & 操作符或 intersection() 方法可以取交集
set1 = {1, 2, 3}
set2 = {2, 3, 4}
# 使用 & 操作符
intersection = set1 & set2 # {2, 3}
# 使用 intersection() 方法
intersection_method = set1.intersection(set2) # {2, 3}
Python里面set的操作:
1. 交集(Intersection)
- 使用?
&
?操作符或?intersection()
?方法: -
set1 = {1, 2, 3} set2 = {2, 3, 4} # 使用 & 操作符 intersection = set1 & set2 # {2, 3} # 使用 intersection() 方法 intersection_method = set1.intersection(set2) # {2, 3}
2. 并集(Union)
- 使用?
|
?操作符或?union()
?方法: -
union = set1 | set2 # {1, 2, 3, 4} union_method = set1.union(set2) # {1, 2, 3, 4}
3. 差集(Difference)
- 使用?
-
?操作符或?difference()
?方法: -
difference = set1 - set2 # {1} difference_method = set1.difference(set2) # {1}
4. 對稱差集(Symmetric Difference)
- 使用?
^
?操作符或?symmetric_difference()
?方法: -
symmetric_difference = set1 ^ set2 # {1, 4} symmetric_difference_method = set1.symmetric_difference(set2) # {1, 4}
5. 添加元素
- 使用?
add()
?方法: -
my_set.add(4) # 現在 my_set 是 {1, 2, 3, 4}
6. 移除元素
- 使用?
remove()
?方法(如果元素不存在會拋出異常):my_set.remove(2) # 現在 my_set 是 {1, 3, 4}
- ?使用?
discard()
?方法(如果元素不存在不會拋出異常):my_set.discard(5) # my_set 仍然是 {1, 3, 4}
- 使用?
pop()
?方法(移除并返回集合中的一個元素,如果集合為空則拋出異常):removed_element = my_set.pop() # 移除并返回集合中的一個元素
7. 判斷元素是否存在
- 使用?
in
?關鍵字:if 3 in my_set: print("3 exists in the set")
8. 集合的長度
- 使用?
len()
?函數:print(len(my_set)) # 輸出集合中元素的數量
9. 轉換為列表
- 使用?
list()
?函數:list_from_set = list(my_set) # 將集合轉換為列表
Python (字典和集合):
class Solution:def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:table = {}for num in nums1:table[num] = table.get(num,0) + 1res= set()for num in nums2:if num in table:res.add(num)del table[num]return list(res)
del table[num]:
在Python中,del table[num]
這行代碼的作用是刪除字典(如果table
是一個字典)或者列表(如果table
是一個列表)中索引或鍵為num
的元素。不過,重要的是要理解這兩種數據結構之間的差異以及如何使用它們。
如果table
是一個列表(List)
在列表中,num
應該是一個整數索引,它指定了要刪除的元素的位置。例如:
table = [1, 2, 3, 4, 5]
num = 2
del table[num] # 刪除索引為2的元素,即數字3
print(table) # 輸出: [1, 2, 4, 5]
如果table
是一個字典(Dictionary)
在字典中,num
應該是一個字符串或不可變類型(如整數、浮點數等,但在實際使用中字符串作為鍵更為常見),它指定了要刪除的鍵值對的鍵。例如:
table = {'a': 1, 'b': 2, 'c': 3}
num = 'b'
del table[num] # 刪除鍵為'b'的鍵值對
print(table) # 輸出: {'a': 1, 'c': 3}
注意點
-
如果
num
的索引或鍵在table
中不存在,使用del table[num]
將會拋出一個KeyError
(對于字典)或IndexError
(對于列表)異常。 -
在處理列表或字典時,如果不確定索引或鍵是否存在,可以先使用
in
關鍵字進行檢查,例如:if num in table: del table[num] else: print(f"The key {num} does not exist in the table.")
-
字典的鍵是唯一的,而列表的索引是基于位置的,這意呀著你可以有重復的列表項,但每個列表項的索引都是唯一的。在字典中,你不能有重復的鍵。
python(數組方法):
class Solution:def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:count1 = [0]*1001count2 = [0]*1001res = []for i in range(len(nums1)):count1[nums1[i]] += 1for i in range(len(nums2)):count2[nums2[i]] += 1for i in range(1001):if count1[i]*count2[i] > 0:res.append(i)return res