Leetcode ブラッシング ノート (C++) - ハッシュ テーブル
質問をブラッシュアップする過程でアイデアを整理し、ここにまとめて共有します。
github アドレス: https://github.com/lvjian0706/Leetcode-solutions
github プロジェクトは新しく作成されたばかりで、C++ と Python をベースに整理されたコードやアイデアが次々とアップロードされます。同時に、基本的な並べ替えアルゴリズムも並べ替えてアップロードされます。
1. 2 つの数値の合計
整数配列 nums とターゲット値 target が与えられた場合、配列内で合計がターゲット値となる 2 つの整数を見つけて、それらの配列の添字を返してください。
各入力に対して答えは 1 つだけであると想定できます。ただし、配列内の同じ要素を 2 回使用することはできません。
例:
nums = [2, 7, 11, 15]、target = 9 の
場合、nums[0] + nums[1] = 2 + 7 = 9
なので、[0, 1] が返されます。
class Solution {
public:
/*
在该数组中找出和为目标值的那两个整数,并返回他们的数组下标:使用哈希表存放已遍历元素即可;
1. 定义哈希表用于存放已遍历元素,其中键为该元素,值为元素索引;
2. 遍历数组,当target-nums[i]在哈希表中不存在时,将该元素存入哈希表中;
3. 当target-nums[i]存在时,则说明target-nums[i]对应的值(该元素索引)以及当前元素的位置i即为答案;
*/
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> nums_map;
vector<int> ans;
for(int i=0; i<nums.size(); i++){
map<int, int>::iterator iter = nums_map.find(target-nums[i]);
if(iter == nums_map.end()){
nums_map[nums[i]] = i;
}
else{
ans.push_back(iter->second);
ans.push_back(i);
break;
}
}
return ans;
}
};
217. 重複した要素が存在します
整数の配列を指定して、重複する要素があるかどうかを確認します。
配列内に値が少なくとも 2 回出現する場合、この関数は true を返します。配列内のすべての要素が異なる場合は false を返します。
例 1:
入力: [1,2,3,1]
出力: true
例 2:
入力: [1,2,3,4]
出力: false
例 3:
入力: [1,1,1,3,3, 4,3,2,4,2]
出力: true
class Solution {
public:
/*
给定一个整数数组,判断是否存在重复元素。
方法1: 排序后判断前后元素是否相同,略;
方法2: 使用Set或者哈希表保存不同元素,在保存过程中,判断当前元素是否已经在Set或者哈希表中出现过,如果有,则存在重复元素;
*/
bool containsDuplicate(vector<int>& nums) {
set<int> no_duplicate;
for(int i=0; i<nums.size(); i++){
if(no_duplicate.find(nums[i]) == no_duplicate.end()){
no_duplicate.insert(nums[i]);
}
else return true;
}
return false;
}
};
242. 有効なアナグラム
2 つの文字列 s と t が与えられた場合、t が s のアナグラムであるかどうかを判断する関数を作成します。
例 1:
入力: s = "anagram"、t = "nagaram"
出力: true
例 2:
入力: s = "rat"、t = "car"
出力: false
説明:
文字列には小文字のみが含まれていると想定できます。 。
class Solution {
public:
/*
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
使用哈希表判断两个字符串中字母出现次数是否一致即可;
1. 新建map存放s中字母出现次数;
2. 遍历t,当t中字母在哈希表中不存在或者个数为0时,返回false;
*/
bool isAnagram(string s, string t) {
if(s.length() != t.length()) return false;
map<char, int> s_map;
for(int i=0; i<s.length(); i++){
if(s_map.find(s[i]) == s_map.end()){
s_map[s[i]] = 1;
}
else s_map[s[i]]++;
}
for(int j=0; j<t.length(); j++){
if(s_map.find(t[j]) == s_map.end() || s_map[t[j]]==0) return false;
else s_map[t[j]]--;
}
return true;
}
};
387. 文字列内の最初の一意の文字
文字列を指定すると、その最初の一意の文字を検索し、そのインデックスを返します。存在しない場合は -1 を返します。
例:
s = "leetcode"
は 0 を返します。
s = "loveleetcode"
は 2 を返します
。 ヒント: 文字列には小文字のみが含まれていると想定できます。
class Solution {
public:
/*
找到字符串的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
使用哈希表遍历两遍字符串即可;
第一遍遍历保存字符出现次数,第二次遍历找第一个出现次数为1的字符;
*/
int firstUniqChar(string s) {
map<char, int> num_char;
for(int i=0; i<s.length(); i++){
if(num_char.find(s[i]) == num_char.end()){
num_char[s[i]] = 1;
}
else num_char[s[i]]++;
}
for(int i=0; i<s.length(); i++){
if(num_char[s[i]]==1) return i;
}
return -1;
}
};