序文
Little KのLeetcodeへようこそ| コードのランダムな思考|テーマ別コラム、今日はハッシュ法〜効果的なアナグラム | 2 つの配列の積分 | 2 つの数値の合計のシェアをお届けします✨
242. 有効なアナグラム
✨タイトルリンクはここをクリック
2 つの文字列 s と t が与えられた場合、t が s のアナグラムであるかどうかを判断する関数を作成します。注: s と t の各文字が同じ回数出現する場合、s と t は互いのアナグラムであると言われます。
例 1:
入力: s = "アナグラム"、t = "ナガラム"
出力: true
例 2:
入力: s = "rat"、t = "car"
出力: false
ヒント:
1 <= s.length, t.length
<= 5 * 104
s と t には小文字のみが含まれます
アイデア:
この問題を解決するためにハッシュ法を使用し、配列をハッシュ テーブルとして使用します (文字列は小文字であり、その ASCII コード値は連続しています)。では、サイズ 26 の配列を直接定義するにはどうすればよいでしょうか
?
0-25にマッピングする方法ですa-z
。現在の値から直接aを減算できます。
具体的な方法
は、配列を0に初期化し、文字列1を走査します。文字が1回出現すると、対応する位置の要素が1ずつインクリメントされ、同様に文字列2を走査します。文字列が1回出現すると、対応する位置の要素が1減ります。配列の要素が最後にすべて0であれば、文字列1と文字列2がanaであることを意味します。お互いのグラム数、そうでない場合は返すfalse
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {
0};
for (int i = 0; i < s.size(); i++) record[s[i]-'a']++;
for (int j = 0; j < t.size(); j++) record[t[j]-'a']--;
for (int k = 0; k < 26; k++) {
if (record[k] != 0)
return false;
}
return true;
}
};
349. 2 つの配列の交差
✨タイトルリンクはこちら
2 つの配列nums1
と が与えられた場合nums2
、それらの共通部分を返します。出力内の各要素は一意である必要があります。出力結果の順序は無視できます。
例 1:
入力: nums1 = [1,2,2,1]、nums2 = [2,2]
出力: [2]
例 2:
入力: nums1 = [4,9,5]、nums2 = [9,4,9,8,4]
出力: [9,4]
説明: [4,9] も可
ヒント:
1 <= nums1.length, nums2.length
<= 1000
0 <= nums1[i], nums2[i]
<= 1000
[方法 1]: を使用しunordered_set
、配列の値を格納し、2 番目の配列を走査し、最初の配列で 2 番目の配列の値を見つけ、見つかった場合は結果の配列に挿入します。
チップ:
C++ set find - 指定された値 val を持つ要素を検索する関数。要素が見つかった場合はその要素を指すイテレータを返し、それ以外の場合はコレクションの終わりを指すイテレータ、つまり set::end() を返します。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result;
unordered_set<int> nums(nums1.begin(),nums1.end());
for (int num : nums2) {
if (nums.find(num) != nums.end()) {
result.insert(num);
}
}
return vector<int>(result.begin(),result.end());
}
};
【方法2】:配列の長さが1000以内なので、配列をハッシュテーブルとして使用する
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
int hashTable[1005] = {
0};
unordered_set<int> result;
for (int a : nums1) hashTable[a] = 1;
for (int b : nums2) {
if (hashTable[b] == 1) {
result.insert(b);
}
}
return vector<int>(result.begin(),result.end());
}
};
1. 2 つの数値の合計
✨タイトルリンクポイントはこちら
整数配列nums
と整数ターゲット値が与えられた場合target
、target
配列内で合計がターゲット値となる2つの整数を見つけて、それらの配列の添字を返してください。各入力に対して答えが 1 つだけあると想定できます。ただし、配列内の同じ要素を回答内に繰り返し出現させることはできません。回答は任意の順序で返すことができます。
例 1:
入力: nums = [2,7,11,15]、ターゲット = 9
出力: [0,1]
説明: nums[0] + nums[1] == 9 なので、[0, 1] を返します。
例 2:
入力: 数値 = [3,2,4]、ターゲット = 6
出力: [1,2]
例 3:
入力: 数値 = [3,3]、ターゲット = 6
出力: [0,1]
ヒント:
2 <= nums.length
<= 104
-109 <= nums[i]
<= 109
-109 <= target
<= 109
有効な答えは 1 つだけです
【方法1】:暴力、2層for
循環直接乾燥
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for (int i = 0; i < nums.size(); i++) {
for (int j = i+1; j < nums.size(); j++) {
if (nums[i] + nums[j] == target) {
return {
i,j};
}
}
}
return {
};
}
};
[方式2]:ハッシュ方式
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> map;
for (int i = 0; i < nums.size(); i++) {
auto iter = map.find(target - nums[i]);
if (iter != map.end()){
return {
iter->second,i};
}
map.insert(pair<int, int>(nums[i], i));
}
return {
};
}
};
要約する
要素がセットに含まれるかどうかをすばやく判断する必要がある場合は、hash~~ を検討してください。