代码随想录算法训练营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中流和集合的掌握有欠缺,补!

  1. 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;
	}
}
  1. 数组解法
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;
	}
}

两数之和

  1. 暴力解
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;
	}
}
  1. 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];
	}
}
posted @ 2025-03-31 23:00  Anson_502  阅读(36)  评论(0)    收藏  举报