代码随想录算法训练营Day06
哈希表
什么时候使用哈希法,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
有效的字母异位词
用数组!
class Solution {
public boolean isAnagram(String s, String t) {
char[] schar = s.toCharArray();
char[] tchar = t.toCharArray();
int[] hash = new int[26];
for(char i : schar){
hash[i-'a']++;//将字符转为数组下标
}
for(char i : tchar){
hash[i-'a']--;
}
for(int i = 0;i<hash.length;i++){
if(hash[i]!=0){
return false;
}
}
return true;
}
}
赎金信
和上面的区别在于,上面要求字母应该完全相同,下面只要求杂志能组成赎金信,可以多,但不能少
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
// 定义一个哈希映射数组
int[] record = new int[26];
// 遍历
for(char c : magazine.toCharArray()){
record[c - 'a'] += 1;
}
for(char c : ransomNote.toCharArray()){
record[c - 'a'] -= 1;
}
//magazine可以有用不完的字符,但是数组中一定不能存在负数
// 如果数组中存在负数,说明ransomNote字符串中存在magazine中没有的字符
for(int i : record){
if(i < 0){
return false;
}
}
return true;
}
}
两个数组的交集
将nums1转换为哈希表,再查nums1中是否包含nums2中的元素,如果存在,则保存在set集合result中
这里对Java中流和集合的掌握有欠缺,补!
- Set解法
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> nums1Set = new HashSet<Integer>();
HashSet<Integer> result = new HashSet<Integer>();
for (int i : nums1) {
nums1Set.add(i);
}
for (int i : nums2) {
if (nums1Set.contains(i)) {
result.add(i);
}
}
int[] res = result.stream().mapToInt(i -> i).toArray();//将set转化为数组
return res;
}
}
- 数组解法
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
int[] temp = new int[1001];
HashSet<Integer> set = new HashSet<Integer>();
for(int i : nums1){
temp[i]++;
}
for(int i : nums2){
if(temp[i] != 0){
set.add(i);
}
}
int[] res = set.stream().mapToInt(i -> i).toArray();//将set转化为数组
return res;
}
}
快乐数
class Solution {
public boolean isHappy(int n) {
HashSet<Integer> set = new HashSet<Integer>();
//使用集合记录已经出现过的数字,检测循环
//题目中说了会无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要
while (n != 1 && !set.contains(n)) {
set.add(n);
n = getValue(n);
}
return n == 1;
}
public int getValue(int n) {
int sum = 0;
while (n > 0) {
int num = n % 10;
sum += num * num;
n /= 10;
}
return sum;
}
}
两数之和
- 暴力解
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
for(int i = 0;i<nums.length;i++){
for(int j = 0;j<nums.length;j++){
int sum = nums[i] + nums[j];
if(sum == target&&i!=j){
result[0] = i;
result[1] = j;
}
}
}
return result;
}
}
- HashMap
for循环遍历,当遍历到nums[i]时,则判断target-nums[i]是否存在,如果存在,则返回i和target-nums[i]的下标
这里的put顺序问题:你在将当前元素nums[i]和它的索引i放入map后,立即检查map.containsKey(target - nums[i])。这会导致错误,因为当前元素已经被放入map,它可能会与自己形成匹配,从而返回错误的结果。
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
// 检查是否存在匹配的键
if (map.containsKey(target - nums[i])) {
return new int[]{map.get(target - nums[i]), i};
}
// 将当前元素和索引放入 map
map.put(nums[i], i);
}
return new int[0];
}
}

浙公网安备 33010602011771号