[Code Random Records] Hash table brushing questions

Tips:

  • The data range is small, and an array can be used to simulate hashing
  • It is important to think clearly about what is the key of the hash
  • Some problems seem to require two hash tables, but can actually be solved with one

valid anagrams

Title: 242. Valid anagrams

Given two strings  s and  t , write a function to determine  t whether they are  s anagrams of .
Note : If  the number of occurrences of each character in s and  t is the same, it is said that  s and  t are anagrams of each other.

输入: s = "anagram", t = "nagaram"
输出: true

Array analog hashing:

public boolean isAnagram(String s, String t) {
    
    
	if (s.length() != t.length()) return false;
	int[] map = new int[128];
	for (char c : s.toCharArray()) map[c]++;
	for (char c : t.toCharArray())
		if (--map[c] < 0) return false;
	for (int i : map) if (i != 0) return false;
	return true;
}

Sort by:

public boolean isAnagram(String s, String t) {
    
    
	char[] cs1 = s.toCharArray();
	char[] cs2 = t.toCharArray();
	Arrays.sort(cs1);
	Arrays.sort(cs2);
	return String.valueOf(cs1).equals(String.valueOf(cs2));
}

ransom letter

Title: 383. Ransom Letter - LeetCode

Give you two strings: ransomNote and  magazine , to judge  ransomNote whether it can be  magazine composed of characters inside.
Return if yes  true ; otherwise return  false .
magazine Each character in can only  ransomNote be used once in .

输入:ransomNote = "a", magazine = "b"
输出:false

Array analog hashing:

public boolean canConstruct(String s1, String s2) {
    
    
	int[] map = new int[123]; // s2 中字符出现的次数
	for (char c : s2.toCharArray()) map[c]++;
	for (char c : s1.toCharArray()) if (--map[c] < 0) return false;
	return true;
}

Anagram grouping*

Topic: 49. Grouping of anagrams - LeetCode

Given an array of strings, please combine  anagrams  together. The list of results can be returned in any order.
An anagram  is a new word obtained by rearranging the letters of a source word, usually in all of the source words exactly once.

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

After sorting the two anagrams , the result is the same.

public List<List<String>> groupAnagrams(String[] strs) {
    
    
	Map<String, List<String>> map = new HashMap<>();
	for (String s : strs) {
    
    
		// 对字符数组进行排序, 排序后的字符串作为哈希表的 key
		char[] cs = s.toCharArray();
		Arrays.sort(cs);
		String key = String.valueOf(cs);
		System.out.println(key);
		if (!map.containsKey(key)) map.put(key, new ArrayList<>());
		map.get(key).add(s);
	}
	return new ArrayList<>(map.values());
}

Find all anagrams in a string

Title: 438. Find all anagrams in a string - LeetCode

Given two strings  s and  p, find   all  substrings of anagramss  in   and return the starting indices of these substrings. The order in which answers are output is not considered. An anagram  refers to a character string (including the same character string) formed by rearranging the same letter.p

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

Double pointer + array analog hash: similar to [[01_array#minimum coverage substring]]

public List<Integer> findAnagrams(String s, String p) {
    
    
	List<Integer> res = new ArrayList<>();
	int[] map = new int[123]; 
	for (char c : p.toCharArray()) map[c]++; // map[c] < 0 表示满足需求
	int cnt = 0; // cnt == p.length() 表示满足需求
	for (int l = 0, r = 0; r < s.length(); r++) {
    
    
		if (map[s.charAt(r)]-- > 0) cnt++;
		while (l < r && map[s.charAt(l)] < 0) map[s.charAt(l++)]++;
		if (r - l + 1 == cnt && cnt == p.length()) 
			res.add(l);
	}
	return res;
}

intersection of two arrays

Title: 349. Intersection of Two Arrays - LeetCode

Given two arrays  nums1 and sum  nums2 , return  their intersection  . Each element in the output must be  unique  . We can  ignore the order of the output results  .

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
public int[] intersection(int[] nums1, int[] nums2) {
    
    
	int[] map = new int[1001];
	List<Integer> list = new ArrayList<>();
	for (int n : nums1) map[n]++;
	for (int n : nums2) {
    
    
		if (map[n] != 0) {
    
    
			list.add(n);
			map[n] = 0; // *
		}
	}
	int[] res = new int[list.size()];
	for (int i = 0; i < res.length; i++)
		res[i] = list.get(i);
	return res;
}

Intersection of Two Arrays II

Title: 350. Intersection of Two Arrays II - LeetCode

Given the sum of two integer arrays  nums1 ,  nums2 please return the intersection of the two arrays as an array. The number of occurrences of each element in the returned result should be consistent with the number of occurrences of the element in both arrays (if the number of occurrences is inconsistent, consider taking a smaller value). The order of the output results can be ignored.

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
class Solution {
    
    
    public int[] intersect(int[] nums1, int[] nums2) {
    
    
        int[] map = new int[1001];
        for (int n : nums1) map[n]++;
        List<Integer> list = new ArrayList<>();
        for (int n : nums2) {
    
    
            if (map[n] != 0) {
    
    
                list.add(n);
                map[n]--; // *
            }
        }
        int[] res = new int[list.size()];
        for (int i = 0; i < res.length; i++)
            res[i] = list.get(i);
        return res;
    }
}

happy number

Topic: Happy Numbers

Write an algorithm to determine  n whether a number is a happy number.
"Happy Number"  is defined as:

  • For a positive integer, each time the number is replaced by the sum of the squares of the digits in each position.
  • Then repeat this process until the number becomes 1, or it may be  an infinite loop  but it never becomes less than 1.
  • If  the result of this process is  1, then the number is a happy number.
    If  n it is  a happy number  , it returns  true ; if it is not, it returns  false .
输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
class Solution {
    
    
    public boolean isHappy(int n) {
    
    
        Set<Integer> set = new HashSet<>();
        while (n != 1) {
    
    
            n = squareSum(n);
            if (set.contains(n)) return false;
            set.add(n);
        }
        return true;
    }
    int squareSum(int n) {
    
    
        int sum = 0;
        while (n != 0) {
    
    
            sum += Math.pow(n % 10, 2);
            n /= 10;
        }
        return sum;
    }
}   

sum of two numbers

Topic: 1. The sum of two numbers

Given an integer array  nums and an integer target value  , please find the two integers   whose  sum is the target valuetarget in the array   , and return their array subscripts. You can assume that there is only one answer for each input. However, the same element in the array cannot appear repeatedly in the answer. You can return answers in any order. target

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
public int[] twoSum(int[] nums, int target) {
    
    
	Map<Integer, Integer> map = new HashMap<>();
	for (int i = 0; i < nums.length; i++) {
    
    
		if (map.containsKey(target - nums[i]))
			return new int[] {
    
     i, map.get(target - nums[i]) };
		map.put(nums[i], i);
	}
	return new int[] {
    
    };
}

Adding Four Numbers II

Topic: 454. Adding Four Numbers II

Given you four integer arrays  nums1, nums2, nums3 and  nums4 , the lengths of the arrays are all  n , please calculate how many tuples  (i, j, k, l) can satisfy:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0

Think of n1 + n2 as a hash key:

public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
    
    
	Map<Integer, Integer> map = new HashMap<>();
	int count = 0;
	for (int n1 : nums1)
		for (int n2 : nums2)
			map.put(n1 + n2, map.getOrDefault(n1 + n2, 0) + 1);
	for (int n3 : nums3)
		for (int n4 : nums4)
			if (map.containsKey(-n3 - n4))
				count += map.get(-n3 - n4);
	return count;
}

sum of three numbers

Topic: 15. Sum of Three Numbers - LeetCode

Given an array of integers  nums , determine whether there is a triple  [nums[i], nums[j], nums[k]] that satisfies  i != j, i != k and  j != k , and satisfies at the same time  nums[i] + nums[j] + nums[k] == 0 . Please
return all  0 triples whose sum is and are not repeated.
Note : Duplicate triplets are not allowed in the answer.

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

Pay attention to combining sorting to remove duplication:

public List<List<Integer>> threeSum(int[] nums) {
    
    
	List<List<Integer>> res = new ArrayList<>();
	int n = nums.length;
	Arrays.sort(nums); // 排序
	for (int i = 0; i < n; i++) {
    
    
		if (nums[i] > 0) break;
		if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
		int l = i + 1, r = n - 1;
		while (l < r) {
    
    
			if (nums[l] + nums[r] < -nums[i]) l++;
			else if (nums[l] + nums[r] > -nums[i]) r--;
			else {
    
    
				res.add(Arrays.asList(nums[i], nums[l], nums[r]));
				while (l < r && nums[l] == nums[l + 1]) l++; // 去重
				while (l < r && nums[r] == nums[r - 1]) r--; // 去重
				l++;
				r--;
			}
		}
	}
	return res;
}

sum of four numbers

Topic: 18. Sum of Four Numbers - LeetCode

You are given an  n array of integers  nums , and a target value  target . Please find and return the quadruples  that meet all the following conditions and are not repeated [nums[a], nums[b], nums[c], nums[d]] (if the two quadruple elements correspond to each other, the two quadruples are considered to be repeated):

  • 0 <= a, b, c, d < n
  • a, b, c and  d are different from each other
  • nums[a] + nums[b] + nums[c] + nums[d] == target
    You can return answers in  any order  .
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
public List<List<Integer>> fourSum(int[] nums, int target) {
    
    
	List<List<Integer>> res = new ArrayList<>();
	int n = nums.length;
	Arrays.sort(nums);
	for (int i = 0; i < n - 3; i++) {
    
    
		if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
		// 剪枝: 最小的情况 > target 则不可能满足; 最大的情况 < target 有可能满足
		if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break;
		if ((long) nums[i] + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) continue;
		for (int j = i + 1; j < n - 2; j++) {
    
    
			if (j > i + 1 && nums[j] == nums[j - 1]) continue; // 去重
			// 剪枝: 最小的情况 > target 则不可能满足; 最大的情况 < target 有可能满足
			if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) break;
			if ((long) nums[i] + nums[j] + nums[n - 2] + nums[n - 1] < target) continue;
			int l = j + 1, r = n - 1;
			while (l < r) {
    
    
				long sum = (long) nums[i] + nums[j] + nums[l] + nums[r]; // 防止溢出
				if (sum < target) l++;
				else if (sum > target) r--;
				else {
    
    
					res.add(Arrays.asList(nums[i], nums[j], nums[l], nums[r]));
					while (l < r && nums[l] == nums[l + 1]) l++; // 去重
					while (l < r && nums[r] == nums[r - 1]) r--; // 去重
					l++; 
					r--;
				}
			}
		}
	}
	return res;
}

Guess you like

Origin blog.csdn.net/weixin_43734095/article/details/126774770