題目
- 242: Valid Anagram
- 1002: Find Common Characters
- 349: Intersection of Two Arrays
- 202: Happy Number
- 1: Two Sum
知識點
通常 HashTable 用來快速判斷一個元素是否在集合中。
常見的結構為:
- Array
- Set: 可以粗暴理解為重複 value 的 Array。
- Map: key value pair 的集合,key 不能重複。
242. Valid Anagram
https://leetcode.com/problems/valid-anagram/
1 | Given two strings s and t, return true if t is an anagram of s, and false otherwise. |
Example 1:
1 | Input: s = "anagram", t = "nagaram" |
Example 2:
1 | Input: s = "rat", t = "car" |
Constraints:
1 | 1 <= s.length, t.length <= 5 * 104 |
解法
直接把 string 中的 char 當 key,然後第一個
字串在每次寫入 array 都 +1
,第二個
字串則 -1
,如果最後 array 的每個元素都是 0
代表兩個字串為 Valid Anagram。
重要: 在取 string 中的 char 時,千萬不要用
s.ElementAt(i)
,這樣效能太慢 leetcode 會直接 Time Limit Exceeded,要寫s[i]
。
1 | public bool IsAnagram(string s, string t) |
1002. Find Common Characters
https://leetcode.com/problems/find-common-characters/
1 | Given a string array words, return an array of all characters that show up in all strings within the words (including duplicates). You may return the answer in any order. |
Example 1:
1 | Input: words = ["bella","label","roller"] |
Example 2:
1 | Input: words = ["cool","lock","cook"] |
Constraints:
1 | 1 <= words.length <= 100 |
思路
題目可以理解為每個字母在所有字串中都出現的話就列出來。
延續使用 HashTable,紀錄 string 每個 char 出現的次數後,把所有紀錄整合起來,每個 char 出現的次數取最小值,如果為 0 則代表該 char 在所有 string 中都沒有出現,反之大於 0 則是在所有 string 中都有出現。
EX:
1 | "abc" => [1, 1, 1, 0, 0] |
每個 char 出現次數取最小後: [0, 0, 1, 0, 0]
,所以得知 c
同時出現在兩組字串中。
解法
1 | public IList<string> CommonChars(string[] words) |
349. Intersection of Two Arrays
https://leetcode.com/problems/intersection-of-two-arrays/
1 | Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must be unique and you may return the result in any order. |
Example 1:
1 | Input: nums1 = [1,2,2,1], nums2 = [2,2] |
Example 2:
1 | Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] |
Constraints:
1 | 1 <= nums1.length, nums2.length <= 1000 |
思路
前面兩題都是英文字母,會使用的空間就是 26 個而已,所以使用 Array[26] 來當 HashTable。
但這題變成數字,
- 雖然有限定範圍在 1000 內,但資料有可能過於分散或太少而浪費空間
- 題目限定 result 必須 unique
故此處改用 HashSet
。
其實也可以使用兩層 for 暴力法,但時間複雜度為 O(n^2)
。
而用 HashSet
查詢的時間複雜度為 O(1)
,所以整體時間複雜度就變為 O(n)
。
解法
1 | public int[] Intersection(int[] nums1, int[] nums2) |
202. Happy Number
https://leetcode.com/problems/happy-number/
1 | Write an algorithm to determine if a number n is happy. |
Example 1:
1 | Input: n = 19 |
Example 2:
1 | Input: n = 2 |
Constraints:
1 | 1 <= n <= 231 - 1 |
思路
題目說可能無法算出 1
進而無限循環,乍看之下很麻煩,但其實可以理解為: 進入無限循環意味著每一輪的計算結果曾經出現
。
如果要判過一個元素是否存在,那就進入 HashTable 的守備範圍了。
解法
1 | public bool IsHappy(int n) |
1. Two Sum
https://leetcode.com/problems/two-sum/
1 | Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target. |
Example 1:
1 | Input: nums = [2,7,11,15], target = 9 |
Example 2:
1 | Input: nums = [3,2,4], target = 6 |
Example 3:
1 | Input: nums = [3,3], target = 6 |
Constraints:
1 | 2 <= nums.length <= 104 |
思路
LeetCode 第一題,夢想痛苦開始的地方。
可以用兩層 for 暴力解,但也可以透過 HashTable 來解,時間複雜度為 O(n)
。
這題解題思路為: 每次迭代時,都嘗試去找 Array 中是否存在與其相加為 target 的值
。
EX:
1 | Input: [1, 2, 3],Target = 4 |
那就是
第一輪 1
的時候,嘗試找出 4 - 1 = 3
第二輪 2
的時候,嘗試找出 4 - 2 = 2
第三輪 3
的時候,嘗試找出 4 - 3 = 1
要確認某個元素是否在集合中,又進入 HashTable 的守備範圍了,只是這次需要 return index,所以要用 map (C# 為 HashTable
) 來同時存 key & value。
解法
此題把 HashTable 的 key
用來存 Array 的值,value
用來存 index。
1 | public int[] TwoSum(int[] nums, int target) |