LeetCode中的数据结构4:查找表

Java中的Set和Map底层是哈希表实现,哈希表的缺点是失去了数据的顺序性。
如果需要数据的顺序性,需要使用底层是二叉查找树的实现。

349 Intersection of Two Arrays
https://leetcode.com/problems/intersection-of-two-arrays/
Given two arrays, write a function to compute their intersection.
Set的基本操作。

public int[] intersection(int[] nums1, int[] nums2) {
    Set<Integer> set = new HashSet<>();
    for (int i=0; i<nums1.length; i++) {
        set.add(nums1[i]);
    }
    Set<Integer> resSet = new HashSet<>();
    for (int i=0; i<nums2.length; i++) {
        if (set.contains(nums2[i])) {
            resSet.add(nums2[i]);
        }
    }
    int[] res = new int[resSet.size()];
    int i=0;
    for (int n : resSet) {
        res[i++] = n;
    }
    return res;
}

350 Intersection of Two Arrays II
https://leetcode.com/problems/intersection-of-two-arrays-ii/
Given two arrays, write a function to compute their intersection.
Map的基本操作。

public int[] intersect(int[] nums1, int[] nums2) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i=0; i<nums1.length; i++) {
        if (map.containsKey(nums1[i])) {
            map.put(nums1[i],(map.get(nums1[i])+1));
        } else {
            map.put(nums1[i], 1);
        }
    }
    int[] res = new int[nums1.length];
    int j=0;
    for (int i=0; i<nums2.length; i++) {
        if (map.containsKey(nums2[i]) && map.get(nums2[i])>0) {
            map.put(nums2[i], map.get(nums2[i])-1);
            res[j++] = nums2[i];
        }
    }
    int[] resTrim = new int[j];
    for (int i=0; i<j; i++) {
        resTrim[i] = res[i];
    }
    return resTrim;
}

242 Valid Anagram
https://leetcode.com/problems/valid-anagram/
Given two strings s and t , write a function to determine if t is an anagram of s.
判断 t 是否是 s 的字母异位词。统计s和t各字母出现的次数是否相等即可。数组就是最基础的查找表实现。

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

202 Happy Number
https://leetcode.com/problems/happy-number
Write an algorithm to determine if a number is “happy”. A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
将每一步计算的结果存放到set中,若出现重复的数据,说明进入死循环,不可能是快乐数。

public boolean isHappy(int n) {
    Set<Integer> set = new HashSet<>();
    while (n != 1) {
        if (set.contains(n)) {
            return false;
        }
        set.add(n);
        int temp = n;
        n=0;
        while (temp != 0) {
            n+=(temp%10) * (temp%10);
            temp = temp/10;
        }
    }
    return true;
}

290 Word Pattern
https://leetcode.com/problems/word-pattern/
Given a pattern and a string str, find if str follows the same pattern. Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.
判断映射关系。注意需要互相对应,如pattern = “abba”, str = "dog cat cat dog"正确,但pattern = “abba”, str = "dog dog dog dog"错误。也就是说a对应dog,dog也只能对应a。

public boolean wordPattern(String pattern, String str) {
    String[] arr = str.split(" ");
    if (arr.length != pattern.length()) {
        return false;
    }
    Map<Character, String> map1 = new HashMap<>();
    Map<String, Character> map2 = new HashMap<>();
    for (int i=0; i<arr.length; i++) {
        if (map1.containsKey(pattern.charAt(i)) 
            && !map1.get(pattern.charAt(i)).equals(arr[i])) {
            return false;
        }
        if (map2.containsKey(arr[i]) 
            && !map2.get(arr[i]).equals(pattern.charAt(i))) {
            return false;
        }
        if (!map1.containsKey(pattern.charAt(i)) && !map2.containsKey(arr[i])) {
            map1.put(pattern.charAt(i), arr[i]);
            map2.put(arr[i], pattern.charAt(i));
        }
    }
    return true;
}

205 Isomorphic Strings
https://leetcode.com/problems/isomorphic-strings/
Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.
这个题目和上面一个一样的问题,换一个容器解决。

public boolean isIsomorphic(String s, String t) {
    if (s.length() != t.length()) {
        return false;
    }
    Map<Character, Character> map1 = new HashMap<>();
    Map<Character, Character> map2 = new HashMap<>();
    for (int i=0; i<s.length(); i++) {
        if (map1.containsKey(s.charAt(i)) 
            && !map1.get(s.charAt(i)).equals(t.charAt(i))) {
            return false;
        }
        if (map2.containsKey(t.charAt(i)) 
            && !map2.get(t.charAt(i)).equals(s.charAt(i))) {
            return false;
        }
        if (!map1.containsKey(s.charAt(i)) && !map2.containsKey(t.charAt(i))) {
            map1.put(s.charAt(i), t.charAt(i));
            map2.put(t.charAt(i), s.charAt(i));
        }
    }
    return true;
}

451 Sort Characters By Frequency
https://leetcode.com/problems/sort-characters-by-frequency/
Given a string, sort it in decreasing order based on the frequency of characters.


1 Two Sum
https://leetcode.com/problems/two-sum/
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
将数组中所有数据都放入map,然后遍历数组,在map中找target-nums[i]。

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    int[] res = new int[2];
    for (int i=0; i<nums.length; i++) {
        map.put(nums[i], i);
    }
    for (int i=0; i<nums.length; i++) {
        if (map.containsKey(target - nums[i]) && map.get(target - nums[i]) != i) {
            res[0] = i;
            res[1] = map.get(target - nums[i]);
        }
    }
    return res;
}

由Two Sum引申出的题目还有:
15 3Sum
https://leetcode.com/problems/3sum/
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.


18 4Sum
https://leetcode.com/problems/4sum
Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.


16 3Sum Closest
https://leetcode.com/problems/3sum-closest/
Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.


454 4Sum II
https://leetcode.com/problems/4sum-ii/
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero.

public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
    Map<Integer, Integer> abMap = new HashMap<>();
    for(int i=0; i<A.length; i++){
        for(int j=0; j<B.length; j++){
            int ans = A[i]+B[j];
            if(abMap.get(ans) == null){
                abMap.put(ans, 1);
            } else {
                abMap.put(ans, abMap.get(ans)+1);
            }
        }
    }                
    int rst = 0;
    for(int i=0; i<C.length; i++){
        for(int j=0; j<D.length; j++){
            if(abMap.get(0-C[i]-D[j]) != null){
                rst += abMap.get(0-C[i]-D[j]);
            }
        }
    }        
    return rst;
}

49 Group Anagrams
https://leetcode.com/problems/group-anagrams/
Given an array of strings, group anagrams together.

public List<List<String>> groupAnagrams(String[] strs) {
    Map<String, List<String>> map = new HashMap<>();
    for (String str : strs) {
        int[] arr = new int[26];
        for (char c : str.toCharArray()) {
            arr[c-'a']++;
        }
        StringBuilder sb = new StringBuilder("");
        for (int j=0; j<26; j++) {
            sb.append("#");
            sb.append(arr[j]);
        }
        String key = sb.toString();
        if (!map.containsKey(key)) {
            List<String> list = new ArrayList<>();
            map.put(key, list);
        } 
        map.get(key).add(str);
    }
    return new ArrayList(map.values());
}

上面的方法是将a-z的词频拼接成字符串做key,也可以将a-z转换为质数,用其乘积做key。这个就要你熟记100以内的质数啦,我就背的很清楚,因为小学的时候被罚抄100遍。。。如下,

public List<List<String>> groupAnagrams(String[] strs) {
	int[] prime = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 103};
	Map<Integer, List<String>> map = new HashMap<>();
	for (String str : strs) {
	    int key = 1;
	    for (char c : str.toCharArray()) {
	        key *= prime[c-'a'];
	    }
	    if (! map.containsKey(key)) {
	        map.put(key, new ArrayList<>());
	    }
	    map.get(key).add(str);
	}
	return new ArrayList<List<String>>(map.values());
	}

447 Number of Boomerangs
https://leetcode.com/problems/number-of-boomerangs/
Given n points in the plane that are all pairwise distinct, a “boomerang” is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters).
寻找组合i 和 j 之间的距离和 i 和 k 之间的距离相等。

public int numberOfBoomerangs(int[][] points) {        
    int rst = 0;
    Map<Integer, Integer> disMap = new HashMap<>();
    for(int i=0; i<points.length; i++){
        int[] point1 = points[i];            
        for(int j=0; j<points.length; j++){
            int[] point2 = points[j];
            if(i!=j){
                int dis = (point1[0]-point2[0])*(point1[0]-point2[0])+(point1[1]-point2[1])*(point1[1]-point2[1]);
                disMap.put(dis, disMap.getOrDefault(dis, 0)+1);
            }
        }
        for(int value : disMap.values()){
            rst += value*(value-1);
        }
        disMap.clear();
    }                
    return rst;
}

149 Max Points on a Line
https://leetcode.com/problems/max-points-on-a-line/
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.


217 Contains Duplicate
https://leetcode.com/problems/contains-duplicate/
Given an array of integers, find if the array contains any duplicates.
Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.

public boolean containsDuplicate(int[] nums) {
    Set<Integer> set = new HashSet<>();
    for(int i = 0; i < nums.length; i++){
        if(set.contains(nums[i])){
            return true;
        } 
        set.add(nums[i]);
    }
    return false;
}

219 Contains Duplicate II
https://leetcode.com/problems/contains-duplicate-ii/
Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.
在上个题目的基础上,i和j的距离不能超过k。

public boolean containsNearbyDuplicate(int[] nums, int k) {
    if(nums.length<2 || k<1){
        return false;
    }
    int i = 0;
    int j = 1;        
    Set<Integer> set = new HashSet<>();
    set.add(nums[i]);
    while(j<nums.length){
        if(set.contains(nums[j])){
            return true;
        }else if(j-i<k){
            set.add(nums[j]);
            j++;
        }else{
            set.remove(nums[i]);
            set.add(nums[j]);
            i++;
            j++;
        }
    }      
    return false;
}

220 Contains Duplicate III
https://leetcode.com/problems/contains-duplicate-iii/
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章