Day5 | Part1
约 528 个字 173 行代码 2 张图片 预计阅读时间 4 分钟
介绍
HashTable: 用来快速判断一个元素是否出现在集合中
用哈希法,一般选择三种数据结构:
- 数组:长度受到限制,若元素少而哈希值大则造成内存空间泄露
- set(集合):里面放的只能是一个key
- map(映射):
<key, value>
的存储结构
在C++中,set 和 map 分别提供三种数据结构:
总:当要使用集合来解决哈希问题的时候,优先使用unordered_set
,因为它的查询和增删效率是最优的,如果需要集合是 有序 的,那么就用set
,如果要求不仅 有序还要有重复数据 的话,那么就用multiset
判断字符串s是否可以通过改变顺序的方式变成字符串t
思路:映射到26bits的数组即可(a:0,b:1...
),对每个s中的元素在数组中对应加1,对t的每个元素在数组中对应减1。若可以转变,则数组应该都为0,返回true,否则返回false → 动图Ref
1、最直接的思路: 排序+双指针 → 时间\(O(n^2)\)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Arrays.sort(nums1); Arrays.sort(nums2);
int idx1 = 0, idx2 = 0, idx = 0;
int [] arr = new int[1010];
while(idx1 < nums1.length && idx2 < nums2.length) {
if(nums1[idx1] == nums2[idx2]) {
if(idx == 0 || arr[idx - 1] != nums1[idx1])
arr[idx ++] = nums1[idx1];
idx1 ++; idx2 ++;
}
else if(nums1[idx1] < nums2[idx2]) idx1 ++;
else idx2 ++;
}
return Arrays.copyOfRange(arr, 0, idx);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(), nums1.end()), sort(nums2.begin(), nums2.end());
int idx1 = 0, idx2 = 0;
vector<int> res;
while(idx1 < nums1.size() && idx2 < nums2.size()) {
if (nums1[idx1] == nums2[idx2]) {
if (!res.size() || res.back() != nums1[idx1]) //保证唯一
res.push_back(nums1[idx1]);
idx1 ++, idx2 ++;
}
else if (nums1[idx1] < nums2[idx2]) idx1 ++;
else idx2 ++;
}
return res;
}
|
2、哈希
- 对n进行求和,赋给另一个数,循环判断是否为1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | int getSum(int n) {
int res = 0;
while(n) {
int t = n % 10;
res += t * t;
n /= 10;
}
return res;
}
bool isHappy(int n) {
int num1 = n, num2 = getSum(n);
while (num1 != num2) {
num1 = getSum(num1);
num2 = getSum(getSum(num2));
}
return num1 == 1;
}
|
- 哈希
1、暴力 → 时间复杂度\(O(n^2)\)
2、 利用哈希