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.


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